From 349de8773fde456744588e2798ad15e8ff5ac51d Mon Sep 17 00:00:00 2001 From: TheMode Date: Mon, 12 Aug 2019 13:27:24 +0200 Subject: [PATCH] Added BlockBatch --- .../minestom/entity/EntityManager.java | 2 +- .../minestom/entity/demo/ChickenCreature.java | 8 ++- .../themode/minestom/instance/BlockBatch.java | 67 +++++++++++++++++++ .../fr/themode/minestom/instance/Chunk.java | 13 ---- .../themode/minestom/instance/Instance.java | 22 +++--- .../themode/minestom/net/PacketProcessor.java | 2 +- .../packet/client/login/LoginStartPacket.java | 4 +- .../ClientPlayerBlockPlacementPacket.java | 9 ++- .../minestom/utils/GroupedCollections.java | 14 +--- 9 files changed, 98 insertions(+), 43 deletions(-) create mode 100644 src/main/java/fr/themode/minestom/instance/BlockBatch.java diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index 2e866b542..56e13e460 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -11,7 +11,7 @@ public class EntityManager { private static InstanceManager instanceManager = Main.getInstanceManager(); - private ExecutorService creaturesPool = Executors.newFixedThreadPool(4); + private ExecutorService creaturesPool = Executors.newFixedThreadPool(2); private ExecutorService playersPool = Executors.newFixedThreadPool(2); public void update() { 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 cab74ea7f..315c2b7b7 100644 --- a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java +++ b/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java @@ -1,6 +1,8 @@ package fr.themode.minestom.entity.demo; +import fr.themode.minestom.Main; import fr.themode.minestom.entity.EntityCreature; +import fr.themode.minestom.entity.Player; public class ChickenCreature extends EntityCreature { @@ -12,10 +14,10 @@ public class ChickenCreature extends EntityCreature { public void update() { double speed = 0.075; - /*Player player = Main.getConnectionManager().getPlayer("TheMode911"); + Player player = Main.getConnectionManager().getPlayer("TheMode911"); if (player != null) { - teleport(player.getX(), 5, player.getZ()); - }*/ + //teleport(player.getX(), 5, player.getZ()); + } move(0, 0, speed); } diff --git a/src/main/java/fr/themode/minestom/instance/BlockBatch.java b/src/main/java/fr/themode/minestom/instance/BlockBatch.java new file mode 100644 index 000000000..a525a152b --- /dev/null +++ b/src/main/java/fr/themode/minestom/instance/BlockBatch.java @@ -0,0 +1,67 @@ +package fr.themode.minestom.instance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class BlockBatch { + + private static volatile ExecutorService batchesPool = Executors.newFixedThreadPool(2); + + private Instance instance; + + private Map> data = new HashMap<>(); + + public BlockBatch(Instance instance) { + this.instance = instance; + } + + public synchronized void setBlock(int x, int y, int z, Block block) { + final int chunkX = Math.floorDiv(x, 16); + final int chunkZ = Math.floorDiv(z, 16); + Chunk chunk = this.instance.getChunk(chunkX, chunkZ); + if (chunk == null) + chunk = this.instance.createChunk(Biome.VOID, chunkX, chunkZ); + List blockData = this.data.getOrDefault(chunk, new ArrayList<>()); + + BlockData data = new BlockData(); + data.x = x % 16; + data.y = y; + data.z = z % 16; + data.block = block; + + blockData.add(data); + + this.data.put(chunk, blockData); + } + + public void flush() { + for (Map.Entry> entry : data.entrySet()) { + Chunk chunk = entry.getKey(); + List dataList = entry.getValue(); + synchronized (chunk) { + batchesPool.submit(() -> { + for (BlockData data : dataList) { + data.apply(chunk); + } + instance.sendChunkUpdate(chunk); + }); + } + } + } + + private class BlockData { + + private int x, y, z; + private Block block; + + public void apply(Chunk chunk) { + chunk.setBlock(x % 16, y, z % 16, block); + } + + } + +} diff --git a/src/main/java/fr/themode/minestom/instance/Chunk.java b/src/main/java/fr/themode/minestom/instance/Chunk.java index d6cb16c58..84262e102 100644 --- a/src/main/java/fr/themode/minestom/instance/Chunk.java +++ b/src/main/java/fr/themode/minestom/instance/Chunk.java @@ -3,7 +3,6 @@ package fr.themode.minestom.instance; import fr.themode.minestom.entity.Entity; import fr.themode.minestom.entity.EntityCreature; import fr.themode.minestom.entity.Player; -import fr.themode.minestom.net.packet.server.play.ChunkDataPacket; import java.util.Collections; import java.util.HashMap; @@ -17,7 +16,6 @@ public class Chunk { private int chunkX, chunkZ; private Biome biome; private HashMap blocks = new HashMap<>(); - private ChunkDataPacket fullChunkPacket; public Chunk(Biome biome, int chunkX, int chunkZ) { this.biome = biome; @@ -90,15 +88,4 @@ public class Chunk { public Set getPlayers() { return Collections.unmodifiableSet(players); } - - private void refreshFullChunkPacket() { - ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); - chunkDataPacket.fullChunk = true; - chunkDataPacket.chunk = this; - // TODO fill buffer - } - - public ChunkDataPacket getFullChunkPacket() { - return fullChunkPacket; - } } diff --git a/src/main/java/fr/themode/minestom/instance/Instance.java b/src/main/java/fr/themode/minestom/instance/Instance.java index 13d9ea251..561b2c2e3 100644 --- a/src/main/java/fr/themode/minestom/instance/Instance.java +++ b/src/main/java/fr/themode/minestom/instance/Instance.java @@ -35,10 +35,14 @@ public class Instance { } synchronized (chunk) { chunk.setBlock(x % 16, y, z % 16, block); - sendChunkUpdate(chunk); // TODO partial chunk data + sendChunkUpdate(chunk); } } + public BlockBatch createBlockBatch() { + return new BlockBatch(this); + } + public Chunk getChunk(int chunkX, int chunkZ) { for (Chunk chunk : getChunks()) { if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ) @@ -102,7 +106,7 @@ public class Instance { return uniqueId; } - private Chunk createChunk(Biome biome, int chunkX, int chunkZ) { + protected Chunk createChunk(Biome biome, int chunkX, int chunkZ) { Chunk chunk = new Chunk(biome, chunkX, chunkZ); this.creatures.addCollection(chunk.creatures); this.players.addCollection(chunk.players); @@ -110,6 +114,13 @@ public class Instance { return chunk; } + protected void sendChunkUpdate(Chunk chunk) { + ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); + chunkDataPacket.fullChunk = true; // TODO partial chunk data + chunkDataPacket.chunk = chunk; + getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(chunkDataPacket)); + } + private void sendChunks(Player player) { ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); chunkDataPacket.fullChunk = true; @@ -118,11 +129,4 @@ public class Instance { player.getPlayerConnection().sendPacket(chunkDataPacket); } } - - private void sendChunkUpdate(Chunk chunk) { - ChunkDataPacket chunkDataPacket = new ChunkDataPacket(); - chunkDataPacket.fullChunk = true; - chunkDataPacket.chunk = chunk; - getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(chunkDataPacket)); - } } diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index d376882ff..ae801df34 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -40,7 +40,7 @@ public class PacketProcessor { public void process(Connection connection, Packet packet) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { int id = packet.get(PACKET_ID_IDENTIFIER); - System.out.println("RECEIVED ID: " + id); + // System.out.println("RECEIVED ID: " + id); Buffer buffer = packet.getPayload(); connectionPlayerConnectionMap.get(connection); PlayerConnection playerConnection = connectionPlayerConnectionMap.computeIfAbsent(connection, c -> new PlayerConnection(c)); 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 1b9e8653c..8e6875296 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 @@ -103,8 +103,8 @@ public class LoginStartPacket implements ClientPreplayPacket { playerInfoPacket.playerInfos.add(addPlayer); connection.sendPacket(playerInfoPacket); - for (int x = -5; x < 5; x++) - for (int z = -5; z < 5; z++) { + for (int x = 0; x < 4; x++) + for (int z = 0; z < 4; z++) { // TODO test entity ChickenCreature chickenCreature = new ChickenCreature(); chickenCreature.refreshPosition(0 + (double) x * 1, 5, 0 + (double) z * 1); diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerBlockPlacementPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerBlockPlacementPacket.java index d30eaaddb..60d3d0fba 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerBlockPlacementPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerBlockPlacementPacket.java @@ -3,6 +3,7 @@ package fr.themode.minestom.net.packet.client.play; import fr.adamaq01.ozao.net.Buffer; import fr.themode.minestom.entity.Player; import fr.themode.minestom.instance.Block; +import fr.themode.minestom.instance.BlockBatch; import fr.themode.minestom.instance.Instance; import fr.themode.minestom.net.packet.client.ClientPlayPacket; import fr.themode.minestom.utils.Position; @@ -21,7 +22,13 @@ public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket { Instance instance = player.getInstance(); if (instance == null) return; - instance.setBlock(position.getX(), position.getY(), position.getZ(), new Block(2)); + + BlockBatch blockBatch = instance.createBlockBatch(); + for (int x = -64; x < 64; x++) + for (int z = -64; z < 64; z++) { + blockBatch.setBlock(x, position.getY() + 1, z, new Block(1)); + } + blockBatch.flush(); } @Override diff --git a/src/main/java/fr/themode/minestom/utils/GroupedCollections.java b/src/main/java/fr/themode/minestom/utils/GroupedCollections.java index 3ea56db83..9fca7bba6 100644 --- a/src/main/java/fr/themode/minestom/utils/GroupedCollections.java +++ b/src/main/java/fr/themode/minestom/utils/GroupedCollections.java @@ -7,7 +7,7 @@ public class GroupedCollections implements Iterable { private Collection> collections; - public GroupedCollections(Collection collection) { + public GroupedCollections(Collection> collection) { this.collections = collection; } @@ -28,18 +28,6 @@ public class GroupedCollections implements Iterable { return collections.stream().flatMap(Collection::stream).iterator(); } - /*public Object[] toArray() { - return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).toArray(); - } - - public T[] toArray(T[] ts) { - return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).toArray(ts); - } - - public boolean containsAll(Collection collection) { - return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).containsAll(collection); - }*/ - public void addCollection(Collection list) { this.collections.add(list); }