Added entity properties & removed unnecessary reflection

This commit is contained in:
TheMode 2019-08-26 00:29:40 +02:00
parent e0eb35e81e
commit b13a888170
14 changed files with 242 additions and 160 deletions

View File

@ -18,4 +18,5 @@ dependencies {
compile 'com.github.Querz:NBT:4.1' compile 'com.github.Querz:NBT:4.1'
// https://mvnrepository.com/artifact/org.lz4/lz4-java // https://mvnrepository.com/artifact/org.lz4/lz4-java
implementation 'com.github.luben:zstd-jni:1.4.3-1' implementation 'com.github.luben:zstd-jni:1.4.3-1'
implementation 'com.esotericsoftware:reflectasm:1.11.9'
} }

View File

@ -17,16 +17,14 @@ import fr.themode.minestom.net.PacketProcessor;
import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; import fr.themode.minestom.net.packet.server.play.KeepAlivePacket;
import fr.themode.minestom.net.protocol.MinecraftProtocol; import fr.themode.minestom.net.protocol.MinecraftProtocol;
import java.lang.reflect.InvocationTargetException;
public class Main { public class Main {
// Thread number // Thread number
public static final int THREAD_COUNT_PACKET_WRITER = 5; 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_IO = 2;
public static final int THREAD_COUNT_CHUNK_BATCH = 2; public static final int THREAD_COUNT_CHUNK_BATCH = 3;
public static final int THREAD_COUNT_ENTITIES = 1; public static final int THREAD_COUNT_ENTITIES = 3;
public static final int THREAD_COUNT_PLAYERS_ENTITIES = 3; public static final int THREAD_COUNT_PLAYERS_ENTITIES = 2;
public static final int TICK_MS = 50; public static final int TICK_MS = 50;
public static final int TICK_PER_SECOND = 1000 / TICK_MS; public static final int TICK_PER_SECOND = 1000 / TICK_MS;
@ -65,12 +63,14 @@ public class Main {
@Override @Override
public void onDisconnect(Server server, Connection connection) { public void onDisconnect(Server server, Connection connection) {
System.out.println("A DISCONNECTION"); System.out.println("A Disconnection");
if (packetProcessor.hasPlayerConnection(connection)) { if (packetProcessor.hasPlayerConnection(connection)) {
Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)); Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection));
if (player != null) { if (player != null) {
Instance instance = player.getInstance(); Instance instance = player.getInstance();
if (instance != null) { if (instance != null) {
instance.removeEntity(player); instance.removeEntity(player);
} }
@ -85,17 +85,7 @@ public class Main {
@Override @Override
public void onPacketReceive(Server server, Connection connection, Packet packet) { public void onPacketReceive(Server server, Connection connection, Packet packet) {
try { packetProcessor.process(connection, packet);
packetProcessor.process(connection, packet);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
} }
@Override @Override

View File

@ -26,11 +26,11 @@ public interface Viewable {
int size = getViewers().size(); int size = getViewers().size();
if (size == 0) if (size == 0)
return; return;
buffer.getData().retain(getViewers().size()).markReaderIndex(); buffer.getData().retain(size).markReaderIndex();
getViewers().forEach(player -> { for (Player viewer : getViewers()) {
player.getPlayerConnection().writeUnencodedPacket(buffer); viewer.getPlayerConnection().writeUnencodedPacket(buffer);
buffer.getData().resetReaderIndex(); buffer.getData().resetReaderIndex();
}); }
}); });
} }
@ -40,11 +40,14 @@ public interface Viewable {
for (ServerPacket packet : packets) { for (ServerPacket packet : packets) {
PacketWriter.writeCallbackPacket(packet, buffer -> { PacketWriter.writeCallbackPacket(packet, buffer -> {
buffer.getData().retain(getViewers().size()).markReaderIndex(); int size = getViewers().size();
getViewers().forEach(player -> { if (size == 0)
player.getPlayerConnection().writeUnencodedPacket(buffer); return;
buffer.getData().retain(size).markReaderIndex();
for (Player viewer : getViewers()) {
viewer.getPlayerConnection().writeUnencodedPacket(buffer);
buffer.getData().resetReaderIndex(); buffer.getData().resetReaderIndex();
}); }
}); });
} }
} }
@ -52,14 +55,15 @@ public interface Viewable {
default void sendPacketToViewersAndSelf(ServerPacket packet) { default void sendPacketToViewersAndSelf(ServerPacket packet) {
if (this instanceof Player) { if (this instanceof Player) {
PacketWriter.writeCallbackPacket(packet, buffer -> { 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); ((Player) this).getPlayerConnection().writeUnencodedPacket(buffer);
buffer.getData().resetReaderIndex(); buffer.getData().resetReaderIndex();
if (!getViewers().isEmpty()) { if (size != 0) {
getViewers().forEach(player -> { for (Player viewer : getViewers()) {
buffer.getData().resetReaderIndex(); buffer.getData().resetReaderIndex();
player.getPlayerConnection().writeUnencodedPacket(buffer); viewer.getPlayerConnection().writeUnencodedPacket(buffer);
}); }
} }
}); });
} }

View File

@ -109,21 +109,7 @@ public abstract class Entity implements Viewable, DataContainer {
if (instance == null) if (instance == null)
return; return;
if (instance.hasEnabledAutoChunkLoad()) { Runnable runnable = () -> {
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;
refreshPosition(position.getX(), position.getY(), position.getZ()); refreshPosition(position.getX(), position.getY(), position.getZ());
refreshView(position.getYaw(), position.getPitch()); refreshView(position.getYaw(), position.getPitch());
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
@ -131,6 +117,18 @@ public abstract class Entity implements Viewable, DataContainer {
entityTeleportPacket.position = position; entityTeleportPacket.position = position;
entityTeleportPacket.onGround = onGround; entityTeleportPacket.onGround = onGround;
sendPacketToViewers(entityTeleportPacket); 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) if (callback != null)
callback.run(); callback.run();
} }
@ -196,7 +194,7 @@ public abstract class Entity implements Viewable, DataContainer {
// Velocity // Velocity
if (velocityTime != 0) { if (velocityTime != 0) {
if (time >= velocityTime) { if (time >= velocityTime) {
// TODO send synchronization packet? sendPositionSynchronization(); // Send synchronization after velocity ended
resetVelocity(); resetVelocity();
} else { } else {
if (this instanceof Player) { if (this instanceof Player) {
@ -215,7 +213,7 @@ public abstract class Entity implements Viewable, DataContainer {
update(); update();
// Synchronization // Scheduled synchronization
if (time - lastSynchronizationTime >= synchronizationDelay) { if (time - lastSynchronizationTime >= synchronizationDelay) {
lastSynchronizationTime = System.currentTimeMillis(); lastSynchronizationTime = System.currentTimeMillis();
sendPositionSynchronization(); sendPositionSynchronization();
@ -309,7 +307,14 @@ public abstract class Entity implements Viewable, DataContainer {
if (instance != null) { if (instance != null) {
SetPassengersPacket passengersPacket = new SetPassengersPacket(); SetPassengersPacket passengersPacket = new SetPassengersPacket();
passengersPacket.vehicleEntityId = getEntityId(); 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); sendPacketToViewers(passengersPacket);
} }
} }

View File

@ -49,13 +49,15 @@ public class EntityManager {
int chunkZ = chunkPos[1]; int chunkZ = chunkPos[1];
boolean isLast = i == visibleChunks.length - 1; boolean isLast = i == visibleChunks.length - 1;
Consumer<Chunk> callback = isLast ? chunk -> { Consumer<Chunk> callback = isLast ? chunk -> {
System.out.println("END CHUNK LOADING");
playerCache.spawned = true; playerCache.spawned = true;
playerCache.setInstance(spawningInstance); playerCache.setInstance(spawningInstance);
PlayerSpawnEvent spawnEvent = new PlayerSpawnEvent(); PlayerSpawnEvent spawnEvent = new PlayerSpawnEvent();
playerCache.callEvent(PlayerSpawnEvent.class, spawnEvent); playerCache.callEvent(PlayerSpawnEvent.class, spawnEvent);
playerCache.updateViewPosition(chunk);
} : null; } : 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);
} }
}); });

View File

@ -1,25 +1,31 @@
package fr.themode.minestom.entity; package fr.themode.minestom.entity;
import fr.adamaq01.ozao.net.Buffer; import fr.adamaq01.ozao.net.Buffer;
import fr.themode.minestom.entity.property.Attribute;
import fr.themode.minestom.event.PickupItemEvent; import fr.themode.minestom.event.PickupItemEvent;
import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Chunk;
import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.ItemStack;
import fr.themode.minestom.net.packet.server.play.CollectItemPacket; import fr.themode.minestom.net.packet.server.play.CollectItemPacket;
import fr.themode.minestom.net.packet.server.play.EntityPropertiesPacket;
import java.util.Set; import java.util.Set;
// TODO attributes https://wiki.vg/Protocol#Entity_Properties
public abstract class LivingEntity extends Entity { public abstract class LivingEntity extends Entity {
protected boolean canPickupItem; protected boolean canPickupItem;
protected boolean isDead; protected boolean isDead;
protected float health;
private float[] attributeValues = new float[Attribute.values().length];
private boolean isHandActive; private boolean isHandActive;
private boolean activeHand; private boolean activeHand;
private boolean riptideSpinAttack; private boolean riptideSpinAttack;
public LivingEntity(int entityType) { public LivingEntity(int entityType) {
super(entityType); super(entityType);
setupAttributes();
} }
public abstract void kill(); public abstract void kill();
@ -73,6 +79,33 @@ public abstract class LivingEntity extends Entity {
return buffer; 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() { public boolean isDead() {
return isDead; return isDead;
} }
@ -94,4 +127,28 @@ public abstract class LivingEntity extends Entity {
public void refreshIsDead(boolean isDead) { public void refreshIsDead(boolean isDead) {
this.isDead = 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());
}
}
} }

View File

@ -4,8 +4,7 @@ import fr.themode.minestom.Main;
import fr.themode.minestom.bossbar.BossBar; import fr.themode.minestom.bossbar.BossBar;
import fr.themode.minestom.chat.Chat; import fr.themode.minestom.chat.Chat;
import fr.themode.minestom.data.Data; import fr.themode.minestom.data.Data;
import fr.themode.minestom.data.DataType; import fr.themode.minestom.entity.property.Attribute;
import fr.themode.minestom.entity.demo.ChickenCreature;
import fr.themode.minestom.event.*; import fr.themode.minestom.event.*;
import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Chunk;
import fr.themode.minestom.instance.CustomBlock; 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.instance.demo.ChunkGeneratorDemo;
import fr.themode.minestom.inventory.Inventory; import fr.themode.minestom.inventory.Inventory;
import fr.themode.minestom.inventory.PlayerInventory; 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.client.ClientPlayPacket;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.net.packet.server.play.*; import fr.themode.minestom.net.packet.server.play.*;
@ -45,6 +43,8 @@ public class Player extends LivingEntity {
private GameMode gameMode; private GameMode gameMode;
private LevelType levelType; private LevelType levelType;
private static InstanceContainer instanceContainer;
static { static {
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
//instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); //instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data"));
@ -62,13 +62,14 @@ public class Player extends LivingEntity {
} }
protected Set<Entity> viewableEntity = new CopyOnWriteArraySet<>(); protected Set<Entity> viewableEntity = new CopyOnWriteArraySet<>();
private float health;
private PlayerSettings settings; private PlayerSettings settings;
private PlayerInventory inventory; private PlayerInventory inventory;
private short heldSlot; private short heldSlot;
private Inventory openInventory; private Inventory openInventory;
private int food; private int food;
private float foodSaturation;
private CustomBlock targetCustomBlock; private CustomBlock targetCustomBlock;
private BlockPosition targetBlockPosition; private BlockPosition targetBlockPosition;
@ -81,17 +82,15 @@ public class Player extends LivingEntity {
private float sideways; private float sideways;
private float forward; private float forward;
private static InstanceContainer instanceContainer;
private float foodSaturation;
protected boolean spawned; protected boolean spawned;
public Player(UUID uuid, String username, PlayerConnection playerConnection) { public Player(UUID uuid, String username, PlayerConnection playerConnection) {
super(93); // FIXME verify super(93);
this.uuid = uuid; this.uuid = uuid;
this.username = username; this.username = username;
this.playerConnection = playerConnection; this.playerConnection = playerConnection;
playerConnection.sendPacket(getPropertiesPacket()); // Send default properties
refreshHealth(); refreshHealth();
this.settings = new PlayerSettings(); this.settings = new PlayerSettings();
@ -115,11 +114,11 @@ public class Player extends LivingEntity {
}); });
setEventCallback(PlayerBlockPlaceEvent.class, event -> { setEventCallback(PlayerBlockPlaceEvent.class, event -> {
sendMessage("Placed block! " + event.getHand()); /*sendMessage("Placed block! " + event.getHand());
int value = getData().getOrDefault("test", 0); int value = getData().getOrDefault("test", 0);
getData().set("test", value + 1, DataType.INTEGER); 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) if (event.getHand() != Hand.MAIN)
return; return;
@ -129,10 +128,10 @@ public class Player extends LivingEntity {
sendMessage("Saved in " + (System.currentTimeMillis() - time) + " ms"); sendMessage("Saved in " + (System.currentTimeMillis() - time) + " ms");
});*/ });*/
/*for (Player player : instance.getPlayers()) { for (Player player : instance.getPlayers()) {
if (player != this) if (player != this)
player.teleport(getPosition()); player.teleport(getPosition());
}*/ }
}); });
setEventCallback(PickupItemEvent.class, event -> { setEventCallback(PickupItemEvent.class, event -> {
@ -146,10 +145,10 @@ public class Player extends LivingEntity {
setEventCallback(PlayerSpawnEvent.class, event -> { setEventCallback(PlayerSpawnEvent.class, event -> {
System.out.println("SPAWN "); System.out.println("SPAWN ");
setGameMode(GameMode.CREATIVE); setGameMode(GameMode.SURVIVAL);
teleport(new Position(0, 66, 0)); teleport(new Position(0, 66, 0));
ChickenCreature chickenCreature = new ChickenCreature(); /*ChickenCreature chickenCreature = new ChickenCreature();
chickenCreature.refreshPosition(2, 65, 2); chickenCreature.refreshPosition(2, 65, 2);
chickenCreature.setInstance(getInstance()); chickenCreature.setInstance(getInstance());
@ -160,7 +159,7 @@ public class Player extends LivingEntity {
itemEntity.setNoGravity(true); itemEntity.setNoGravity(true);
itemEntity.setInstance(getInstance()); itemEntity.setInstance(getInstance());
//itemEntity.remove(); //itemEntity.remove();
} }*/
TeamsPacket teamsPacket = new TeamsPacket(); TeamsPacket teamsPacket = new TeamsPacket();
teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100); teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100);
@ -173,6 +172,9 @@ public class Player extends LivingEntity {
teamsPacket.collisionRule = "never"; teamsPacket.collisionRule = "never";
teamsPacket.entities = new String[]{getUsername()}; teamsPacket.entities = new String[]{getUsername()};
sendPacketToViewersAndSelf(teamsPacket); sendPacketToViewersAndSelf(teamsPacket);
setAttribute(Attribute.MAX_HEALTH, 21);
heal();
}); });
} }
@ -301,7 +303,7 @@ public class Player extends LivingEntity {
connection.sendPacket(getMetadataPacket()); connection.sendPacket(getMetadataPacket());
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) { 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 @Override
public void kill() { public void kill() {
this.isDead = true; 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) { public void sendBlockBreakAnimation(BlockPosition blockPosition, byte destroyStage) {
@ -341,6 +349,9 @@ public class Player extends LivingEntity {
} }
public void damage(float amount) { public void damage(float amount) {
if (getGameMode() == GameMode.CREATIVE)
return;
AnimationPacket animationPacket = new AnimationPacket(); AnimationPacket animationPacket = new AnimationPacket();
animationPacket.entityId = getEntityId(); animationPacket.entityId = getEntityId();
animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE; animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE;
@ -348,23 +359,17 @@ public class Player extends LivingEntity {
setHealth(health - amount); setHealth(health - amount);
} }
public float getHealth() { @Override
return health; public void setAttribute(Attribute attribute, float value) {
super.setAttribute(attribute, value);
if (playerConnection != null)
playerConnection.sendPacket(getPropertiesPacket());
} }
@Override
public void setHealth(float health) { public void setHealth(float health) {
this.health = health; super.setHealth(health);
sendUpdateHealthPacket(); 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() { public int getFood() {
@ -408,12 +413,13 @@ public class Player extends LivingEntity {
spawnPlayerPacket.playerUuid = getUuid(); spawnPlayerPacket.playerUuid = getUuid();
spawnPlayerPacket.position = getPosition(); spawnPlayerPacket.position = getPosition();
sendPacketToViewers(spawnPlayerPacket); sendPacketToViewers(spawnPlayerPacket);
playerConnection.sendPacket(getPropertiesPacket());
sendUpdateHealthPacket();
}); });
} }
private void refreshHealth() { private void refreshHealth() {
// TODO improve heal();
this.health = 20;
this.food = 20; this.food = 20;
this.foodSaturation = 5; this.foodSaturation = 5;
} }
@ -473,8 +479,7 @@ public class Player extends LivingEntity {
} }
UpdateViewPositionPacket updateViewPositionPacket = new UpdateViewPositionPacket(newChunk); updateViewPosition(newChunk);
playerConnection.sendPacket(updateViewPositionPacket);
} }
@Override @Override
@ -625,11 +630,20 @@ public class Player extends LivingEntity {
} }
public void syncEquipment(EntityEquipmentPacket.Slot slot) { public void syncEquipment(EntityEquipmentPacket.Slot slot) {
sendPacketToViewers(getEquipmentPacket(slot));
}
protected EntityEquipmentPacket getEquipmentPacket(EntityEquipmentPacket.Slot slot) {
EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket(); EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket();
equipmentPacket.entityId = getEntityId(); equipmentPacket.entityId = getEntityId();
equipmentPacket.slot = slot; equipmentPacket.slot = slot;
equipmentPacket.itemStack = inventory.getEquipment(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) { public void addPacketToQueue(ClientPlayPacket packet) {

View File

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

View File

@ -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.packet.client.handshake.HandshakePacket;
import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.net.player.PlayerConnection;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -42,7 +41,7 @@ public class PacketProcessor {
private List<Integer> printBlackList = Arrays.asList(17, 18, 19); private List<Integer> 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); int id = packet.get(PACKET_ID_IDENTIFIER);
Buffer buffer = packet.getPayload(); Buffer buffer = packet.getPayload();
connectionPlayerConnectionMap.get(connection); connectionPlayerConnectionMap.get(connection);
@ -66,17 +65,17 @@ public class PacketProcessor {
switch (connectionState) { switch (connectionState) {
case PLAY: case PLAY:
Player player = connectionManager.getPlayer(playerConnection); Player player = connectionManager.getPlayer(playerConnection);
ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); ClientPlayPacket playPacket = (ClientPlayPacket) playPacketsHandler.getPacketInstance(id);
playPacket.read(buffer); playPacket.read(buffer);
player.addPacketToQueue(playPacket); // Processed during player tick update player.addPacketToQueue(playPacket); // Processed during player tick update
break; break;
case LOGIN: case LOGIN:
ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); ClientPreplayPacket loginPacket = (ClientPreplayPacket) loginPacketsHandler.getPacketInstance(id);
loginPacket.read(buffer); loginPacket.read(buffer);
loginPacket.process(playerConnection, connectionManager); loginPacket.process(playerConnection, connectionManager);
break; break;
case STATUS: case STATUS:
ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketClass(id).getDeclaredConstructor().newInstance(); ClientPreplayPacket statusPacket = (ClientPreplayPacket) statusPacketsHandler.getPacketInstance(id);
statusPacket.read(buffer); statusPacket.read(buffer);
statusPacket.process(playerConnection, connectionManager); statusPacket.process(playerConnection, connectionManager);
break; break;

View File

@ -17,7 +17,7 @@ public class PacketWriter {
public static void writeCallbackPacket(ServerPacket serverPacket, Consumer<Buffer> consumer) { public static void writeCallbackPacket(ServerPacket serverPacket, Consumer<Buffer> consumer) {
batchesPool.execute(() -> { batchesPool.execute(() -> {
Packet p = PacketUtils.writePacket(serverPacket); Packet p = PacketUtils.writePacket(serverPacket);
consumer.accept(PacketUtils.encode(p)); // TODO accept in another thread? consumer.accept(PacketUtils.encode(p));
}); });
} }

View File

@ -1,5 +1,6 @@
package fr.themode.minestom.net.packet.client.handler; package fr.themode.minestom.net.packet.client.handler;
import com.esotericsoftware.reflectasm.ConstructorAccess;
import fr.themode.minestom.net.packet.client.ClientPacket; import fr.themode.minestom.net.packet.client.ClientPacket;
import java.util.HashMap; import java.util.HashMap;
@ -7,14 +8,14 @@ import java.util.Map;
public class ClientPacketsHandler { public class ClientPacketsHandler {
private Map<Integer, Class<? extends ClientPacket>> idPacketMap = new HashMap<>(); private Map<Integer, ConstructorAccess<? extends ClientPacket>> constructorAccessMap = new HashMap<>();
public void register(int id, Class<? extends ClientPacket> packet) { public void register(int id, Class<? extends ClientPacket> packet) {
this.idPacketMap.put(id, packet); this.constructorAccessMap.put(id, ConstructorAccess.get(packet));
} }
public Class<? extends ClientPacket> getPacketClass(int id) { public ClientPacket getPacketInstance(int id) {
return idPacketMap.get(id); return constructorAccessMap.get(id).newInstance();
} }
} }

View File

@ -21,26 +21,6 @@ import java.util.UUID;
public class LoginStartPacket implements ClientPreplayPacket { 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; public String username;
@Override @Override
@ -110,51 +90,9 @@ public class LoginStartPacket implements ClientPreplayPacket {
playerInfoPacket.playerInfos.add(addPlayer); playerInfoPacket.playerInfos.add(addPlayer);
connection.sendPacket(playerInfoPacket); 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); Main.getEntityManager().addWaitingPlayer(player);
/*DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
// 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.Node argumentNode = new DeclareCommandsPacket.Node(); DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
argumentNode.flags = 0b1010; argumentNode.flags = 0b1010;
argumentNode.children = new int[0]; argumentNode.children = new int[0];

View File

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

View File

@ -172,7 +172,7 @@ public class Utils {
buffer.putByte((byte) 0); // End display compound buffer.putByte((byte) 0); // End display compound
buffer.putByte((byte) 0); // End nbt TODO buffer.putByte((byte) 0); // End nbt
} }
} }