From b13a8881705905467a508af0bae61721320774fe Mon Sep 17 00:00:00 2001 From: TheMode Date: Mon, 26 Aug 2019 00:29:40 +0200 Subject: [PATCH] Added entity properties & removed unnecessary reflection --- build.gradle | 1 + src/main/java/fr/themode/minestom/Main.java | 24 ++---- .../java/fr/themode/minestom/Viewable.java | 30 ++++--- .../fr/themode/minestom/entity/Entity.java | 41 +++++---- .../minestom/entity/EntityManager.java | 6 +- .../themode/minestom/entity/LivingEntity.java | 59 ++++++++++++- .../fr/themode/minestom/entity/Player.java | 84 +++++++++++-------- .../minestom/entity/property/Attribute.java | 30 +++++++ .../themode/minestom/net/PacketProcessor.java | 9 +- .../fr/themode/minestom/net/PacketWriter.java | 2 +- .../client/handler/ClientPacketsHandler.java | 9 +- .../packet/client/login/LoginStartPacket.java | 64 +------------- .../server/play/EntityPropertiesPacket.java | 41 +++++++++ .../java/fr/themode/minestom/utils/Utils.java | 2 +- 14 files changed, 242 insertions(+), 160 deletions(-) create mode 100644 src/main/java/fr/themode/minestom/entity/property/Attribute.java create mode 100644 src/main/java/fr/themode/minestom/net/packet/server/play/EntityPropertiesPacket.java diff --git a/build.gradle b/build.gradle index ecb0f0f70..a6c911fbb 100644 --- a/build.gradle +++ b/build.gradle @@ -18,4 +18,5 @@ dependencies { compile 'com.github.Querz:NBT:4.1' // https://mvnrepository.com/artifact/org.lz4/lz4-java implementation 'com.github.luben:zstd-jni:1.4.3-1' + implementation 'com.esotericsoftware:reflectasm:1.11.9' } diff --git a/src/main/java/fr/themode/minestom/Main.java b/src/main/java/fr/themode/minestom/Main.java index 273ae9a4d..b3e826684 100644 --- a/src/main/java/fr/themode/minestom/Main.java +++ b/src/main/java/fr/themode/minestom/Main.java @@ -17,16 +17,14 @@ import fr.themode.minestom.net.PacketProcessor; import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; import fr.themode.minestom.net.protocol.MinecraftProtocol; -import java.lang.reflect.InvocationTargetException; - public class Main { // Thread number public static final int THREAD_COUNT_PACKET_WRITER = 5; public static final int THREAD_COUNT_CHUNK_IO = 2; - public static final int THREAD_COUNT_CHUNK_BATCH = 2; - public static final int THREAD_COUNT_ENTITIES = 1; - public static final int THREAD_COUNT_PLAYERS_ENTITIES = 3; + public static final int THREAD_COUNT_CHUNK_BATCH = 3; + public static final int THREAD_COUNT_ENTITIES = 3; + public static final int THREAD_COUNT_PLAYERS_ENTITIES = 2; public static final int TICK_MS = 50; public static final int TICK_PER_SECOND = 1000 / TICK_MS; @@ -65,12 +63,14 @@ public class Main { @Override public void onDisconnect(Server server, Connection connection) { - System.out.println("A DISCONNECTION"); + System.out.println("A Disconnection"); if (packetProcessor.hasPlayerConnection(connection)) { Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)); if (player != null) { Instance instance = player.getInstance(); + + if (instance != null) { instance.removeEntity(player); } @@ -85,17 +85,7 @@ public class Main { @Override public void onPacketReceive(Server server, Connection connection, Packet packet) { - try { - packetProcessor.process(connection, packet); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } + packetProcessor.process(connection, packet); } @Override diff --git a/src/main/java/fr/themode/minestom/Viewable.java b/src/main/java/fr/themode/minestom/Viewable.java index 0c9459023..bb82c936e 100644 --- a/src/main/java/fr/themode/minestom/Viewable.java +++ b/src/main/java/fr/themode/minestom/Viewable.java @@ -26,11 +26,11 @@ public interface Viewable { int size = getViewers().size(); if (size == 0) return; - buffer.getData().retain(getViewers().size()).markReaderIndex(); - getViewers().forEach(player -> { - player.getPlayerConnection().writeUnencodedPacket(buffer); + buffer.getData().retain(size).markReaderIndex(); + for (Player viewer : getViewers()) { + viewer.getPlayerConnection().writeUnencodedPacket(buffer); buffer.getData().resetReaderIndex(); - }); + } }); } @@ -40,11 +40,14 @@ public interface Viewable { for (ServerPacket packet : packets) { PacketWriter.writeCallbackPacket(packet, buffer -> { - buffer.getData().retain(getViewers().size()).markReaderIndex(); - getViewers().forEach(player -> { - player.getPlayerConnection().writeUnencodedPacket(buffer); + int size = getViewers().size(); + if (size == 0) + return; + buffer.getData().retain(size).markReaderIndex(); + for (Player viewer : getViewers()) { + viewer.getPlayerConnection().writeUnencodedPacket(buffer); buffer.getData().resetReaderIndex(); - }); + } }); } } @@ -52,14 +55,15 @@ public interface Viewable { default void sendPacketToViewersAndSelf(ServerPacket packet) { if (this instanceof Player) { PacketWriter.writeCallbackPacket(packet, buffer -> { - buffer.getData().retain(getViewers().size() + 1).markReaderIndex(); + int size = getViewers().size(); + buffer.getData().retain(size + 1).markReaderIndex(); ((Player) this).getPlayerConnection().writeUnencodedPacket(buffer); buffer.getData().resetReaderIndex(); - if (!getViewers().isEmpty()) { - getViewers().forEach(player -> { + if (size != 0) { + for (Player viewer : getViewers()) { buffer.getData().resetReaderIndex(); - player.getPlayerConnection().writeUnencodedPacket(buffer); - }); + viewer.getPlayerConnection().writeUnencodedPacket(buffer); + } } }); } diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index 5ba70b0ea..42c715ac8 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -109,21 +109,7 @@ public abstract class Entity implements Viewable, DataContainer { if (instance == null) return; - if (instance.hasEnabledAutoChunkLoad()) { - instance.loadChunk(position, chunk -> { - refreshPosition(position.getX(), position.getY(), position.getZ()); - refreshView(position.getYaw(), position.getPitch()); - EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); - entityTeleportPacket.entityId = getEntityId(); - entityTeleportPacket.position = position; - entityTeleportPacket.onGround = onGround; - sendPacketToViewers(entityTeleportPacket); - if (callback != null) - callback.run(); - }); - } else { - if (isChunkUnloaded(position.getX(), position.getZ())) - return; + Runnable runnable = () -> { refreshPosition(position.getX(), position.getY(), position.getZ()); refreshView(position.getYaw(), position.getPitch()); EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); @@ -131,6 +117,18 @@ public abstract class Entity implements Viewable, DataContainer { entityTeleportPacket.position = position; entityTeleportPacket.onGround = onGround; sendPacketToViewers(entityTeleportPacket); + }; + + if (instance.hasEnabledAutoChunkLoad()) { + instance.loadChunk(position, chunk -> { + runnable.run(); + if (callback != null) + callback.run(); + }); + } else { + if (isChunkUnloaded(position.getX(), position.getZ())) + return; + runnable.run(); if (callback != null) callback.run(); } @@ -196,7 +194,7 @@ public abstract class Entity implements Viewable, DataContainer { // Velocity if (velocityTime != 0) { if (time >= velocityTime) { - // TODO send synchronization packet? + sendPositionSynchronization(); // Send synchronization after velocity ended resetVelocity(); } else { if (this instanceof Player) { @@ -215,7 +213,7 @@ public abstract class Entity implements Viewable, DataContainer { update(); - // Synchronization + // Scheduled synchronization if (time - lastSynchronizationTime >= synchronizationDelay) { lastSynchronizationTime = System.currentTimeMillis(); sendPositionSynchronization(); @@ -309,7 +307,14 @@ public abstract class Entity implements Viewable, DataContainer { if (instance != null) { SetPassengersPacket passengersPacket = new SetPassengersPacket(); passengersPacket.vehicleEntityId = getEntityId(); - passengersPacket.passengersId = new int[]{entity.getEntityId()}; // TODO all passengers not only the new + + int[] passengers = new int[this.passengers.size()]; + int counter = 0; + for (Entity passenger : this.passengers) { + passengers[counter++] = passenger.getEntityId(); + } + + passengersPacket.passengersId = passengers; sendPacketToViewers(passengersPacket); } } diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index ec29632fe..89c8c17e8 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -49,13 +49,15 @@ public class EntityManager { int chunkZ = chunkPos[1]; boolean isLast = i == visibleChunks.length - 1; Consumer callback = isLast ? chunk -> { - System.out.println("END CHUNK LOADING"); playerCache.spawned = true; playerCache.setInstance(spawningInstance); PlayerSpawnEvent spawnEvent = new PlayerSpawnEvent(); playerCache.callEvent(PlayerSpawnEvent.class, spawnEvent); + playerCache.updateViewPosition(chunk); } : null; - spawningInstance.loadChunk(chunkX, chunkZ, callback); // TODO loadOptionalChunk for not loading chunks when autoload is false + + // WARNING: if auto load is disabled and no chunks are loaded beforehand, player will be stuck. + spawningInstance.loadChunk(chunkX, chunkZ, callback); } }); diff --git a/src/main/java/fr/themode/minestom/entity/LivingEntity.java b/src/main/java/fr/themode/minestom/entity/LivingEntity.java index ee0013998..b1a3b42ea 100644 --- a/src/main/java/fr/themode/minestom/entity/LivingEntity.java +++ b/src/main/java/fr/themode/minestom/entity/LivingEntity.java @@ -1,25 +1,31 @@ package fr.themode.minestom.entity; import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.entity.property.Attribute; import fr.themode.minestom.event.PickupItemEvent; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.net.packet.server.play.CollectItemPacket; +import fr.themode.minestom.net.packet.server.play.EntityPropertiesPacket; import java.util.Set; -// TODO attributes https://wiki.vg/Protocol#Entity_Properties public abstract class LivingEntity extends Entity { protected boolean canPickupItem; protected boolean isDead; + protected float health; + + private float[] attributeValues = new float[Attribute.values().length]; + private boolean isHandActive; private boolean activeHand; private boolean riptideSpinAttack; public LivingEntity(int entityType) { super(entityType); + setupAttributes(); } public abstract void kill(); @@ -73,6 +79,33 @@ public abstract class LivingEntity extends Entity { return buffer; } + public float getHealth() { + return health; + } + + public void setHealth(float health) { + this.health = health; + if (this.health <= 0) { + kill(); + } + } + + public float getMaxHealth() { + return getAttributeValue(Attribute.MAX_HEALTH); + } + + public void heal() { + setHealth(getAttributeValue(Attribute.MAX_HEALTH)); + } + + public void setAttribute(Attribute attribute, float value) { + this.attributeValues[attribute.ordinal()] = value; + } + + public float getAttributeValue(Attribute attribute) { + return this.attributeValues[attribute.ordinal()]; + } + public boolean isDead() { return isDead; } @@ -94,4 +127,28 @@ public abstract class LivingEntity extends Entity { public void refreshIsDead(boolean isDead) { this.isDead = isDead; } + + protected EntityPropertiesPacket getPropertiesPacket() { + EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket(); + propertiesPacket.entityId = getEntityId(); + + int length = Attribute.values().length; + EntityPropertiesPacket.Property[] properties = new EntityPropertiesPacket.Property[length]; + for (int i = 0; i < length; i++) { + Attribute attribute = Attribute.values()[i]; + EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property(); + property.key = attribute.getKey(); + property.value = getAttributeValue(attribute); + properties[i] = property; + } + + propertiesPacket.properties = properties; + return propertiesPacket; + } + + private void setupAttributes() { + for (Attribute attribute : Attribute.values()) { + setAttribute(attribute, attribute.getDefaultValue()); + } + } } diff --git a/src/main/java/fr/themode/minestom/entity/Player.java b/src/main/java/fr/themode/minestom/entity/Player.java index b9376e569..cf107df7b 100644 --- a/src/main/java/fr/themode/minestom/entity/Player.java +++ b/src/main/java/fr/themode/minestom/entity/Player.java @@ -4,8 +4,7 @@ import fr.themode.minestom.Main; import fr.themode.minestom.bossbar.BossBar; import fr.themode.minestom.chat.Chat; import fr.themode.minestom.data.Data; -import fr.themode.minestom.data.DataType; -import fr.themode.minestom.entity.demo.ChickenCreature; +import fr.themode.minestom.entity.property.Attribute; import fr.themode.minestom.event.*; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.CustomBlock; @@ -14,7 +13,6 @@ import fr.themode.minestom.instance.InstanceContainer; import fr.themode.minestom.instance.demo.ChunkGeneratorDemo; import fr.themode.minestom.inventory.Inventory; import fr.themode.minestom.inventory.PlayerInventory; -import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.net.packet.client.ClientPlayPacket; import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.play.*; @@ -45,6 +43,8 @@ public class Player extends LivingEntity { private GameMode gameMode; private LevelType levelType; + private static InstanceContainer instanceContainer; + static { ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); //instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); @@ -62,13 +62,14 @@ public class Player extends LivingEntity { } protected Set viewableEntity = new CopyOnWriteArraySet<>(); - private float health; private PlayerSettings settings; private PlayerInventory inventory; private short heldSlot; private Inventory openInventory; + private int food; + private float foodSaturation; private CustomBlock targetCustomBlock; private BlockPosition targetBlockPosition; @@ -81,17 +82,15 @@ public class Player extends LivingEntity { private float sideways; private float forward; - private static InstanceContainer instanceContainer; - private float foodSaturation; - protected boolean spawned; public Player(UUID uuid, String username, PlayerConnection playerConnection) { - super(93); // FIXME verify + super(93); this.uuid = uuid; this.username = username; this.playerConnection = playerConnection; + playerConnection.sendPacket(getPropertiesPacket()); // Send default properties refreshHealth(); this.settings = new PlayerSettings(); @@ -115,11 +114,11 @@ public class Player extends LivingEntity { }); setEventCallback(PlayerBlockPlaceEvent.class, event -> { - sendMessage("Placed block! " + event.getHand()); + /*sendMessage("Placed block! " + event.getHand()); int value = getData().getOrDefault("test", 0); getData().set("test", value + 1, DataType.INTEGER); - System.out.println("OLD DATA VALUE: " + value); + System.out.println("OLD DATA VALUE: " + value);*/ if (event.getHand() != Hand.MAIN) return; @@ -129,10 +128,10 @@ public class Player extends LivingEntity { sendMessage("Saved in " + (System.currentTimeMillis() - time) + " ms"); });*/ - /*for (Player player : instance.getPlayers()) { + for (Player player : instance.getPlayers()) { if (player != this) player.teleport(getPosition()); - }*/ + } }); setEventCallback(PickupItemEvent.class, event -> { @@ -146,10 +145,10 @@ public class Player extends LivingEntity { setEventCallback(PlayerSpawnEvent.class, event -> { System.out.println("SPAWN "); - setGameMode(GameMode.CREATIVE); + setGameMode(GameMode.SURVIVAL); teleport(new Position(0, 66, 0)); - ChickenCreature chickenCreature = new ChickenCreature(); + /*ChickenCreature chickenCreature = new ChickenCreature(); chickenCreature.refreshPosition(2, 65, 2); chickenCreature.setInstance(getInstance()); @@ -160,7 +159,7 @@ public class Player extends LivingEntity { itemEntity.setNoGravity(true); itemEntity.setInstance(getInstance()); //itemEntity.remove(); - } + }*/ TeamsPacket teamsPacket = new TeamsPacket(); teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100); @@ -173,6 +172,9 @@ public class Player extends LivingEntity { teamsPacket.collisionRule = "never"; teamsPacket.entities = new String[]{getUsername()}; sendPacketToViewersAndSelf(teamsPacket); + + setAttribute(Attribute.MAX_HEALTH, 21); + heal(); }); } @@ -301,7 +303,7 @@ public class Player extends LivingEntity { connection.sendPacket(getMetadataPacket()); for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) { - syncEquipment(slot); // TODO only send packets to "player" and not all viewers + player.playerConnection.sendPacket(getEquipmentPacket(slot)); } } @@ -324,7 +326,13 @@ public class Player extends LivingEntity { @Override public void kill() { this.isDead = true; - setHealth(-1); + refreshIsDead(true); + EntityStatusPacket entityStatusPacket = new EntityStatusPacket(); + entityStatusPacket.entityId = getEntityId(); + entityStatusPacket.status = 3; // Death sound/animation + sendPacketToViewers(entityStatusPacket); + DeathEvent deathEvent = new DeathEvent(); + callEvent(DeathEvent.class, deathEvent); } public void sendBlockBreakAnimation(BlockPosition blockPosition, byte destroyStage) { @@ -341,6 +349,9 @@ public class Player extends LivingEntity { } public void damage(float amount) { + if (getGameMode() == GameMode.CREATIVE) + return; + AnimationPacket animationPacket = new AnimationPacket(); animationPacket.entityId = getEntityId(); animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE; @@ -348,23 +359,17 @@ public class Player extends LivingEntity { setHealth(health - amount); } - public float getHealth() { - return health; + @Override + public void setAttribute(Attribute attribute, float value) { + super.setAttribute(attribute, value); + if (playerConnection != null) + playerConnection.sendPacket(getPropertiesPacket()); } + @Override public void setHealth(float health) { - this.health = health; + super.setHealth(health); sendUpdateHealthPacket(); - if (this.health <= 0) { - // Kill player - refreshIsDead(true); - EntityStatusPacket entityStatusPacket = new EntityStatusPacket(); - entityStatusPacket.entityId = getEntityId(); - entityStatusPacket.status = 3; // Death sound/animation - sendPacketToViewers(entityStatusPacket); - DeathEvent deathEvent = new DeathEvent(); - callEvent(DeathEvent.class, deathEvent); - } } public int getFood() { @@ -408,12 +413,13 @@ public class Player extends LivingEntity { spawnPlayerPacket.playerUuid = getUuid(); spawnPlayerPacket.position = getPosition(); sendPacketToViewers(spawnPlayerPacket); + playerConnection.sendPacket(getPropertiesPacket()); + sendUpdateHealthPacket(); }); } private void refreshHealth() { - // TODO improve - this.health = 20; + heal(); this.food = 20; this.foodSaturation = 5; } @@ -473,8 +479,7 @@ public class Player extends LivingEntity { } - UpdateViewPositionPacket updateViewPositionPacket = new UpdateViewPositionPacket(newChunk); - playerConnection.sendPacket(updateViewPositionPacket); + updateViewPosition(newChunk); } @Override @@ -625,11 +630,20 @@ public class Player extends LivingEntity { } public void syncEquipment(EntityEquipmentPacket.Slot slot) { + sendPacketToViewers(getEquipmentPacket(slot)); + } + + protected EntityEquipmentPacket getEquipmentPacket(EntityEquipmentPacket.Slot slot) { EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket(); equipmentPacket.entityId = getEntityId(); equipmentPacket.slot = slot; equipmentPacket.itemStack = inventory.getEquipment(slot); - sendPacketToViewers(equipmentPacket); + return equipmentPacket; + } + + protected void updateViewPosition(Chunk chunk) { + UpdateViewPositionPacket updateViewPositionPacket = new UpdateViewPositionPacket(chunk); + playerConnection.sendPacket(updateViewPositionPacket); } public void addPacketToQueue(ClientPlayPacket packet) { diff --git a/src/main/java/fr/themode/minestom/entity/property/Attribute.java b/src/main/java/fr/themode/minestom/entity/property/Attribute.java new file mode 100644 index 000000000..db121c309 --- /dev/null +++ b/src/main/java/fr/themode/minestom/entity/property/Attribute.java @@ -0,0 +1,30 @@ +package fr.themode.minestom.entity.property; + +public enum Attribute { + + MAX_HEALTH("generic.maxHealth", 20), + FOLLOW_RANGE("generic.followRange", 32), + KNOCKBACK_RESISTANCE("generic.knockbackResistance", 0), + MOVEMENT_SPEED("generic.movementSpeed", 0.7f), + ATTACK_DAMAGE("generic.attackDamage", 2), + ATTACK_SPEED("generic.attackSpeed", 4), + FLYING_SPEED("generic.flyingSpeed", 0.4f), + HORSE_JUMP_STRENGTH("horse.jumpStrength", 0.7f), + ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawnReinforcements", 0); + + private String key; + private float defaultValue; + + Attribute(String key, float defaultValue) { + this.key = key; + this.defaultValue = defaultValue; + } + + public String getKey() { + return key; + } + + public float getDefaultValue() { + return defaultValue; + } +} diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index 1a708d1e5..670bdcbb3 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -13,7 +13,6 @@ import fr.themode.minestom.net.packet.client.handler.ClientStatusPacketsHandler; import fr.themode.minestom.net.packet.client.handshake.HandshakePacket; import fr.themode.minestom.net.player.PlayerConnection; -import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -42,7 +41,7 @@ public class PacketProcessor { private List printBlackList = Arrays.asList(17, 18, 19); - public void process(Connection connection, Packet packet) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + public void process(Connection connection, Packet packet) { int id = packet.get(PACKET_ID_IDENTIFIER); Buffer buffer = packet.getPayload(); connectionPlayerConnectionMap.get(connection); @@ -66,17 +65,17 @@ public class PacketProcessor { switch (connectionState) { case PLAY: Player player = connectionManager.getPlayer(playerConnection); - ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); + ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketInstance(id); playPacket.read(buffer); player.addPacketToQueue(playPacket); // Processed during player tick update break; case LOGIN: - ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); + ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketInstance(id); loginPacket.read(buffer); loginPacket.process(playerConnection, connectionManager); break; case STATUS: - ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); + ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketInstance(id); statusPacket.read(buffer); statusPacket.process(playerConnection, connectionManager); break; diff --git a/src/main/java/fr/themode/minestom/net/PacketWriter.java b/src/main/java/fr/themode/minestom/net/PacketWriter.java index 21a8c84df..5ff04cdf7 100644 --- a/src/main/java/fr/themode/minestom/net/PacketWriter.java +++ b/src/main/java/fr/themode/minestom/net/PacketWriter.java @@ -17,7 +17,7 @@ public class PacketWriter { public static void writeCallbackPacket(ServerPacket serverPacket, Consumer consumer) { batchesPool.execute(() -> { Packet p = PacketUtils.writePacket(serverPacket); - consumer.accept(PacketUtils.encode(p)); // TODO accept in another thread? + consumer.accept(PacketUtils.encode(p)); }); } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java index ba150ce7a..597ea5aba 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java @@ -1,5 +1,6 @@ package fr.themode.minestom.net.packet.client.handler; +import com.esotericsoftware.reflectasm.ConstructorAccess; import fr.themode.minestom.net.packet.client.ClientPacket; import java.util.HashMap; @@ -7,14 +8,14 @@ import java.util.Map; public class ClientPacketsHandler { - private Map> idPacketMap = new HashMap<>(); + private Map> constructorAccessMap = new HashMap<>(); public void register(int id, Class packet) { - this.idPacketMap.put(id, packet); + this.constructorAccessMap.put(id, ConstructorAccess.get(packet)); } - public Class getPacketClass(int id) { - return idPacketMap.get(id); + public ClientPacket getPacketInstance(int id) { + return constructorAccessMap.get(id).newInstance(); } } 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 4ede546aa..13e8d00f9 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 @@ -21,26 +21,6 @@ import java.util.UUID; public class LoginStartPacket implements ClientPreplayPacket { - // Test - /*private static Instance instance; - - static { - ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); - instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); - //instance = Main.getInstanceManager().createInstance(); - instance.setChunkGenerator(chunkGeneratorDemo); - int loopStart = -2; - int loopEnd = 2; - long time = System.currentTimeMillis(); - for (int x = loopStart; x < loopEnd; x++) - for (int z = loopStart; z < loopEnd; z++) { - instance.loadChunk(x, z, chunk -> { - System.out.println("JE SUIS LE CALLBACK CHUNK"); - }); - } - System.out.println("Time to load all chunks: " + (System.currentTimeMillis() - time) + " ms"); - }*/ - public String username; @Override @@ -110,51 +90,9 @@ public class LoginStartPacket implements ClientPreplayPacket { playerInfoPacket.playerInfos.add(addPlayer); connection.sendPacket(playerInfoPacket); - // Next is optional TODO put all that somewhere else (LoginEvent) - // TODO LoginEvent in another thread (here we are in netty thread) Main.getEntityManager().addWaitingPlayer(player); - - // TODO REMOVE EVERYTHING DOWN THERE - //player.setInstance(instance); - - /*for (int cx = 0; cx < 4; cx++) - for (int cz = 0; cz < 4; cz++) { - ChickenCreature chickenCreature = new ChickenCreature(); - chickenCreature.refreshPosition(0 + (float) cx * 1, 65, 0 + (float) cz * 1); - //chickenCreature.setOnFire(true); - chickenCreature.setInstance(instance); - //chickenCreature.addPassenger(player); - } - - PlayerInventory inventory = player.getInventory(); - inventory.addItemStack(new ItemStack(Material.BOW, (byte) 1)); - inventory.addItemStack(new ItemStack(Material.ARROW, (byte) 100)); - - /*Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre"); - inv.setItemStack(0, new ItemStack(1, (byte) 1)); - player.openInventory(inv); - inv.setItemStack(1, new ItemStack(1, (byte) 2)); - - BossBar bossBar = new BossBar("Bossbar Title", BarColor.BLUE, BarDivision.SEGMENT_12); - bossBar.setProgress(0.75f); - bossBar.addViewer(player); - - for (int ix = 0; ix < 4; ix++) - for (int iz = 0; iz < 4; iz++) { - ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32)); - itemEntity.refreshPosition(ix, 66, iz); - itemEntity.setNoGravity(true); - itemEntity.setInstance(instance); - //itemEntity.remove(); - } - - TestArrow arrow = new TestArrow(player); - arrow.refreshPosition(5, 65, 5); - arrow.setInstance(instance); - arrow.setNoGravity(true); - - DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket(); + /*DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket(); DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); argumentNode.flags = 0b1010; argumentNode.children = new int[0]; diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/EntityPropertiesPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityPropertiesPacket.java new file mode 100644 index 000000000..4907e213b --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityPropertiesPacket.java @@ -0,0 +1,41 @@ +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 EntityPropertiesPacket implements ServerPacket { + + public int entityId; + public Property[] properties; + + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, entityId); + buffer.putInt(properties.length); + for (Property property : properties) { + property.write(buffer); + } + } + + @Override + public int getId() { + return 0x58; + } + + public static class Property { + + public String key; + public double value; + + private void write(Buffer buffer) { + Utils.writeString(buffer, key); + buffer.putDouble(value); + + // TODO Modifiers + Utils.writeVarInt(buffer, 0); + } + } + +} diff --git a/src/main/java/fr/themode/minestom/utils/Utils.java b/src/main/java/fr/themode/minestom/utils/Utils.java index 18fb4ce72..95ee0fb6f 100644 --- a/src/main/java/fr/themode/minestom/utils/Utils.java +++ b/src/main/java/fr/themode/minestom/utils/Utils.java @@ -172,7 +172,7 @@ public class Utils { buffer.putByte((byte) 0); // End display compound - buffer.putByte((byte) 0); // End nbt TODO + buffer.putByte((byte) 0); // End nbt } }