diff --git a/src/main/java/fr/themode/minestom/Main.java b/src/main/java/fr/themode/minestom/Main.java index 7520176e7..fd194a76c 100644 --- a/src/main/java/fr/themode/minestom/Main.java +++ b/src/main/java/fr/themode/minestom/Main.java @@ -19,19 +19,19 @@ import java.lang.reflect.InvocationTargetException; public class Main { - // In-Game Manager - private static EntityManager entityManager; - - // Others + // Networking private static ConnectionManager connectionManager; private static PacketProcessor packetProcessor; private static Server server; - public static void main(String[] args) { - entityManager = new EntityManager(); + // In-Game Manager + private static EntityManager entityManager; + public static void main(String[] args) { connectionManager = new ConnectionManager(); - packetProcessor = new PacketProcessor(connectionManager); + packetProcessor = new PacketProcessor(); + + entityManager = new EntityManager(); server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() { @Override @@ -87,10 +87,12 @@ public class Main { server.bind(25565); System.out.println("Server started"); - long lastTime = System.currentTimeMillis(); + long tickDistance = 50 * 1000000; // 50 ms + long nextTick = System.nanoTime(); + long currentTime; while (true) { - if (System.currentTimeMillis() - lastTime >= 50) { - lastTime = System.currentTimeMillis(); + currentTime = System.nanoTime(); + if (currentTime >= nextTick) { // Tick // Keep Alive Handling @@ -103,6 +105,10 @@ public class Main { // Entities update entityManager.update(); + + // Set next tick update time + currentTime = System.nanoTime(); + nextTick = currentTime + tickDistance - (currentTime - nextTick); } } } diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index d2a2e0a38..2a524fbc6 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -37,8 +37,8 @@ public class Entity { public void addToWorld() { this.isActive = true; EntityManager entityManager = Main.getEntityManager(); - if (this instanceof LivingEntity) { - entityManager.addLivingEntity((LivingEntity) this); + if (this instanceof EntityCreature) { + entityManager.addCreature((EntityCreature) this); } } diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index a20fe499d..27f88bd30 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -1,36 +1,47 @@ package fr.themode.minestom.entity; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; +import fr.themode.minestom.Main; +import fr.themode.minestom.net.ConnectionManager; + +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class EntityManager { - private Set livingEntities = Collections.synchronizedSet(new HashSet<>()); + private Set creatures = Collections.synchronizedSet(new HashSet<>()); - private ExecutorService pool = Executors.newFixedThreadPool(50); + private ExecutorService creaturesPool = Executors.newFixedThreadPool(3); + private ExecutorService playersPool = Executors.newFixedThreadPool(2); + + private ConnectionManager connectionManager = Main.getConnectionManager(); public void update() { - livingEntities.removeIf(livingEntity -> livingEntity.shouldRemove()); + creatures.removeIf(creature -> creature.shouldRemove()); - synchronized (livingEntities) { - Iterator iterator = livingEntities.iterator(); + synchronized (creatures) { + Iterator iterator = creatures.iterator(); while (iterator.hasNext()) { - LivingEntity entity = iterator.next(); - pool.submit(entity::update); + EntityCreature creature = iterator.next(); + creaturesPool.submit(creature::update); } } + + Collection players = connectionManager.getOnlinePlayers(); + Iterator iterator = players.iterator(); + while (iterator.hasNext()) { + Player player = iterator.next(); + playersPool.submit(player::update); + } + } - public Set getEntities() { - return Collections.unmodifiableSet(livingEntities); + public Set getCreatures() { + return Collections.unmodifiableSet(creatures); } - protected void addLivingEntity(LivingEntity livingEntity) { - this.livingEntities.add(livingEntity); + protected void addCreature(EntityCreature creature) { + this.creatures.add(creature); } } 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 e3e76e5d4..aa46d7608 100644 --- a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java +++ b/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java @@ -13,7 +13,7 @@ public class ChickenCreature extends EntityCreature { public void update() { onGround = true; - double speed = 0.01; + double speed = 0.05; double newPos = getZ() + speed; EntityRelativeMovePacket entityRelativeMovePacket = new EntityRelativeMovePacket(); diff --git a/src/main/java/fr/themode/minestom/net/ConnectionManager.java b/src/main/java/fr/themode/minestom/net/ConnectionManager.java index feed6198e..4dcd08224 100644 --- a/src/main/java/fr/themode/minestom/net/ConnectionManager.java +++ b/src/main/java/fr/themode/minestom/net/ConnectionManager.java @@ -7,6 +7,7 @@ import java.util.*; public class ConnectionManager { + private volatile Set players = new HashSet<>(); private volatile Map connectionPlayerMap = new HashMap<>(); public Player getPlayer(PlayerConnection connection) { @@ -14,15 +15,13 @@ public class ConnectionManager { } public Collection getOnlinePlayers() { - return Collections.unmodifiableCollection(connectionPlayerMap.values()); + return Collections.unmodifiableCollection(players); } // Is only used at LoginStartPacket#process - 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); + public void createPlayer(PlayerConnection connection) { + Player player = new Player(connection); + this.players.add(player); + this.connectionPlayerMap.put(connection, player); } } diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index 5cb742c97..d376882ff 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -3,6 +3,7 @@ package fr.themode.minestom.net; import fr.adamaq01.ozao.net.Buffer; import fr.adamaq01.ozao.net.packet.Packet; import fr.adamaq01.ozao.net.server.Connection; +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.client.ClientPreplayPacket; @@ -29,8 +30,8 @@ public class PacketProcessor { private ClientLoginPacketsHandler loginPacketsHandler; private ClientPlayPacketsHandler playPacketsHandler; - public PacketProcessor(ConnectionManager connectionManager) { - this.connectionManager = connectionManager; + public PacketProcessor() { + this.connectionManager = Main.getConnectionManager(); this.statusPacketsHandler = new ClientStatusPacketsHandler(); this.loginPacketsHandler = new ClientLoginPacketsHandler();