From db9549560cb9145ee88628e1f4118e0478676217 Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Wed, 15 Apr 2020 13:20:28 +0200 Subject: [PATCH] Update + added particles --- README.md | 2 + src/main/java/fr/themode/demo/PlayerInit.java | 27 +++--- .../fr/themode/minestom/MinecraftServer.java | 1 + .../minestom/benchmark/BenchmarkManager.java | 4 + .../minestom/collision/BoundingBox.java | 26 +++++- .../fr/themode/minestom/entity/Entity.java | 13 ++- .../minestom/event/PlayerBlockBreakEvent.java | 21 +++++ .../minestom/instance/InstanceContainer.java | 33 ++++--- .../minestom/instance/block/BlockManager.java | 9 +- .../block/rule/BlockPlacementRule.java | 12 ++- .../rule/vanilla/RedstonePlacementRule.java | 11 ++- .../minestom/net/ConnectionManager.java | 8 +- .../client/handler/ClientPacketsHandler.java | 3 +- .../client/status/StatusRequestPacket.java | 7 +- .../packet/server/play/ParticlePacket.java | 10 ++- .../minestom/net/player/PlayerConnection.java | 12 +++ .../themode/minestom/particle/Particle.java | 87 +++++++++++++++++++ .../minestom/particle/ParticleCreator.java | 43 +++++++++ .../minestom/ping/ResponseDataConsumer.java | 10 +++ .../minestom/registry/RegistryMain.java | 52 ++++++++++- .../minestom/registry/RegistryParticle.java | 8 ++ .../minestom/utils/NbtReaderUtils.java | 18 ++++ 22 files changed, 362 insertions(+), 55 deletions(-) create mode 100644 src/main/java/fr/themode/minestom/particle/Particle.java create mode 100644 src/main/java/fr/themode/minestom/particle/ParticleCreator.java create mode 100644 src/main/java/fr/themode/minestom/ping/ResponseDataConsumer.java create mode 100644 src/main/java/fr/themode/minestom/registry/RegistryParticle.java diff --git a/README.md b/README.md index 38c35368e..a85cd9d04 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ An example of how to use the Minestom library is available [here](src/main/java/ Minecraft evolved a lot since its release, most of the servers today do not take advantage of vanilla features and even have to struggle because of them. Our target audience is those who want to make a completely different server compared to default Minecraft gamemode such as survival or creative building. The goal is to offer more performance for those who need it, Minecraft being single-threaded is the most important problem for them. +In other words, it makes sense to use Minestom when it takes less time to implement everything you want than removing everything you don't need. + # API features Even if we do not include anything by default in the game, we simplify the way you add them, here is a preview. diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java index f99eb1d9c..f7884a098 100644 --- a/src/main/java/fr/themode/demo/PlayerInit.java +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -1,10 +1,8 @@ package fr.themode.demo; -import fr.themode.demo.entity.ChickenCreature; import fr.themode.demo.generator.ChunkGeneratorDemo; import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.benchmark.BenchmarkManager; -import fr.themode.minestom.benchmark.ThreadResult; import fr.themode.minestom.entity.Entity; import fr.themode.minestom.entity.EntityCreature; import fr.themode.minestom.entity.GameMode; @@ -16,13 +14,12 @@ import fr.themode.minestom.inventory.InventoryType; import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.net.ConnectionManager; import fr.themode.minestom.timer.TaskRunnable; -import fr.themode.minestom.utils.MathUtils; import fr.themode.minestom.utils.Position; import fr.themode.minestom.utils.Vector; import fr.themode.minestom.utils.time.TimeUnit; import fr.themode.minestom.utils.time.UpdateOption; -import java.util.Map; +import java.util.UUID; public class PlayerInit { @@ -51,10 +48,10 @@ public class PlayerInit { MinecraftServer.getSchedulerManager().addRepeatingTask(new TaskRunnable() { @Override public void run() { - long ramUsage = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); - ramUsage /= 1e6; // To MB + long ramUsage = benchmarkManager.getUsedMemory(); + ramUsage /= 1e6; // bytes to MB - String benchmarkMessage = ""; + /*String benchmarkMessage = ""; for (Map.Entry resultEntry : benchmarkManager.getResultMap().entrySet()) { String name = resultEntry.getKey(); ThreadResult result = resultEntry.getValue(); @@ -66,7 +63,7 @@ public class PlayerInit { benchmarkMessage += "\n"; } if (benchmarkMessage.length() > 0) - System.out.println(benchmarkMessage); + System.out.println(benchmarkMessage);*/ for (Player player : connectionManager.getOnlinePlayers()) { player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", "", '&'); @@ -74,12 +71,14 @@ public class PlayerInit { } }, new UpdateOption(5, TimeUnit.TICK)); - connectionManager.setResponseDataConsumer(responseData -> { + connectionManager.setResponseDataConsumer((playerConnection, responseData) -> { responseData.setName("1.15.2"); responseData.setProtocol(578); responseData.setMaxPlayer(100); responseData.setOnline(0); - responseData.setDescription("test"); + responseData.addPlayer("A name", UUID.randomUUID()); + responseData.addPlayer("Could be some message", UUID.randomUUID()); + responseData.setDescription("IP test: " + playerConnection.getRemoteAddress()); responseData.setFavicon("data:image/png;base64,"); }); @@ -114,8 +113,8 @@ public class PlayerInit { p.teleport(player.getPosition()); } - ChickenCreature chickenCreature = new ChickenCreature(player.getPosition()); - chickenCreature.setInstance(player.getInstance()); + //ChickenCreature chickenCreature = new ChickenCreature(player.getPosition()); + //chickenCreature.setInstance(player.getInstance()); }); @@ -128,7 +127,7 @@ public class PlayerInit { }); player.setEventCallback(PlayerSpawnEvent.class, event -> { - player.setGameMode(GameMode.CREATIVE); + player.setGameMode(GameMode.SURVIVAL); player.teleport(new Position(0, 66, 0)); /*Random random = new Random(); @@ -159,7 +158,7 @@ public class PlayerInit { }); inventory.setItemStack(0, item.clone()); - player.openInventory(inventory); + //player.openInventory(inventory); player.getInventory().addItemStack(new ItemStack((short) 1, (byte) 100)); diff --git a/src/main/java/fr/themode/minestom/MinecraftServer.java b/src/main/java/fr/themode/minestom/MinecraftServer.java index 2528557ea..8b7cec75c 100644 --- a/src/main/java/fr/themode/minestom/MinecraftServer.java +++ b/src/main/java/fr/themode/minestom/MinecraftServer.java @@ -100,6 +100,7 @@ public class MinecraftServer { RegistryMain.registerItems(); RegistryMain.registerEntities(); RegistryMain.registerSounds(); + RegistryMain.registerParticles(); minecraftServer = new MinecraftServer(); diff --git a/src/main/java/fr/themode/minestom/benchmark/BenchmarkManager.java b/src/main/java/fr/themode/minestom/benchmark/BenchmarkManager.java index 9a48e313b..59333d865 100644 --- a/src/main/java/fr/themode/minestom/benchmark/BenchmarkManager.java +++ b/src/main/java/fr/themode/minestom/benchmark/BenchmarkManager.java @@ -74,6 +74,10 @@ public class BenchmarkManager { this.enabled = false; } + public long getUsedMemory() { + return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + } + public Map getResultMap() { return Collections.unmodifiableMap(resultMap); } diff --git a/src/main/java/fr/themode/minestom/collision/BoundingBox.java b/src/main/java/fr/themode/minestom/collision/BoundingBox.java index 09de67ca2..96563a9b5 100644 --- a/src/main/java/fr/themode/minestom/collision/BoundingBox.java +++ b/src/main/java/fr/themode/minestom/collision/BoundingBox.java @@ -25,10 +25,34 @@ public class BoundingBox { (getMinZ() <= boundingBox.getMaxZ() && getMaxZ() >= boundingBox.getMinZ()); } + // FIXME: seems to do not work properly public boolean intersect(BlockPosition blockPosition) { final float x = 1.6f; final float y = 1; final float z = 1.6f; + + float minX = blockPosition.getX() - (x / 2) + 0.5f; + float maxX = blockPosition.getX() + (x / 2) + 0.5f; + + float minY = blockPosition.getY(); + float maxY = blockPosition.getY() + y; + + float minZ = blockPosition.getZ() - (z / 2) + 0.5f; + float maxZ = blockPosition.getZ() + (z / 2) + 0.5f; + + if (getMinX() > maxX) return false; + if (getMaxX() < minX) return false; + if (getMinY() > maxY) return false; + if (getMaxY() < minY) return false; + if (getMinZ() > maxZ) return false; + return !(getMaxZ() < minZ); + } + + + /*public boolean intersect(BlockPosition blockPosition) { + final float x = 1.6f; + final float y = 1; + final float z = 1.6f; float minX = blockPosition.getX() - (x / 2) + 0.5f; float maxX = blockPosition.getX() + (x / 2) + 0.5f; @@ -42,7 +66,7 @@ public class BoundingBox { boolean checkY = getMinY() + y < maxY && getMaxY() + y > minY; boolean checkZ = getMinZ() + z / 2 < maxZ && getMaxZ() - z / 2 > minZ; return checkX && checkY && checkZ; - } + }*/ public boolean intersect(float x, float y, float z) { return (x >= getMinX() && x <= getMaxX()) && diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index 43790d21e..79e113d77 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -226,10 +226,15 @@ public abstract class Entity implements Viewable, DataContainer { boolean xAir = getInstance().getBlockId(xBlock) == Material.AIR.getId(); boolean yAir = getInstance().getBlockId(yBlock) == Material.AIR.getId(); boolean zAir = getInstance().getBlockId(zBlock) == Material.AIR.getId(); - System.out.println(xAir + " : " + yAir + " : " + zAir); - newX = xAir ? newX : boundingBox.intersect(xBlock) ? Math.round(position.getX()) : newX; - newY = yAir ? newY : boundingBox.intersect(yBlock) ? Math.round(position.getY()) : newY; - newZ = zAir ? newZ : boundingBox.intersect(zBlock) ? Math.round(position.getZ()) : newZ; + + boolean xIntersect = boundingBox.intersect(xBlock); + boolean yIntersect = boundingBox.intersect(yBlock); + boolean zIntersect = boundingBox.intersect(zBlock); + + System.out.println(xIntersect + " : " + yIntersect + " : " + zIntersect); + newX = xAir ? newX : xIntersect ? position.getX() : newX; + newY = yAir ? newY : yIntersect ? position.getY() : newY; + newZ = zAir ? newZ : zIntersect ? position.getZ() : newZ; refreshPosition(newX, newY, newZ); if (this instanceof ObjectEntity) { diff --git a/src/main/java/fr/themode/minestom/event/PlayerBlockBreakEvent.java b/src/main/java/fr/themode/minestom/event/PlayerBlockBreakEvent.java index e47eb7fc4..97aab7b84 100644 --- a/src/main/java/fr/themode/minestom/event/PlayerBlockBreakEvent.java +++ b/src/main/java/fr/themode/minestom/event/PlayerBlockBreakEvent.java @@ -6,6 +6,9 @@ public class PlayerBlockBreakEvent extends CancellableEvent { private BlockPosition blockPosition; + private short blockId; + private boolean customBlock; + public PlayerBlockBreakEvent(BlockPosition blockPosition) { this.blockPosition = blockPosition; } @@ -13,4 +16,22 @@ public class PlayerBlockBreakEvent extends CancellableEvent { public BlockPosition getBlockPosition() { return blockPosition; } + + public short getResultBlock() { + return blockId; + } + + public void setResultBlock(short blockId) { + this.blockId = blockId; + this.customBlock = false; + } + + public boolean isResultCustomBlock() { + return customBlock; + } + + public void setResultCustomBlock(short customBlockId) { + this.blockId = customBlockId; + this.customBlock = true; + } } diff --git a/src/main/java/fr/themode/minestom/instance/InstanceContainer.java b/src/main/java/fr/themode/minestom/instance/InstanceContainer.java index 79aa01266..fb298751f 100644 --- a/src/main/java/fr/themode/minestom/instance/InstanceContainer.java +++ b/src/main/java/fr/themode/minestom/instance/InstanceContainer.java @@ -11,6 +11,8 @@ import fr.themode.minestom.instance.block.rule.BlockPlacementRule; import fr.themode.minestom.net.PacketWriterUtils; import fr.themode.minestom.net.packet.server.play.BlockChangePacket; import fr.themode.minestom.net.packet.server.play.ParticlePacket; +import fr.themode.minestom.particle.Particle; +import fr.themode.minestom.particle.ParticleCreator; import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.ChunkUtils; import fr.themode.minestom.utils.SerializerUtils; @@ -165,23 +167,26 @@ public class InstanceContainer extends Instance { PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(blockPosition); player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent); if (!blockBreakEvent.isCancelled()) { - // TODO blockbreak setBlock result int x = blockPosition.getX(); int y = blockPosition.getY(); int z = blockPosition.getZ(); - setBlock(x, y, z, (short) 0); - ParticlePacket particlePacket = new ParticlePacket(); // TODO change to a proper particle API - particlePacket.particleId = 3; // Block particle - particlePacket.longDistance = false; - particlePacket.x = x + 0.5f; - particlePacket.y = y; - particlePacket.z = z + 0.5f; - particlePacket.offsetX = 0.4f; - particlePacket.offsetY = 0.5f; - particlePacket.offsetZ = 0.4f; - particlePacket.particleData = 0.3f; - particlePacket.particleCount = 125; - particlePacket.blockId = blockId; + + // Break or change the broken block based on event result + short resultBlockId = blockBreakEvent.getResultBlock(); + boolean custom = blockBreakEvent.isResultCustomBlock(); + if (custom) { + setCustomBlock(x, y, z, resultBlockId); + } else { + setBlock(x, y, z, resultBlockId); + } + + ParticlePacket particlePacket = ParticleCreator.createParticlePacket(Particle.BLOCK, false, + x + 0.5f, y, z + 0.5f, + 0.4f, 0.5f, 0.4f, + 0.3f, 125, writer -> { + writer.writeVarInt(blockId); + }); + chunk.sendPacketToViewers(particlePacket); } else { sendChunkSectionUpdate(chunk, ChunkUtils.getSectionAt(blockPosition.getY()), player); diff --git a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java index 5149abcc2..a548088f5 100644 --- a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java +++ b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java @@ -12,7 +12,7 @@ public class BlockManager { private Short2ObjectMap blocksInternalId = new Short2ObjectOpenHashMap<>(); private Map blocksId = new HashMap<>(); - private Map placementRules = new HashMap<>(); + private Short2ObjectOpenHashMap placementRules = new Short2ObjectOpenHashMap<>(); public void registerCustomBlock(CustomBlock customBlock) { String identifier = customBlock.getIdentifier(); @@ -22,12 +22,13 @@ public class BlockManager { } public void registerBlockPlacementRule(BlockPlacementRule blockPlacementRule) { - this.placementRules.put(blockPlacementRule.getBlock(), blockPlacementRule); + this.placementRules.put(blockPlacementRule.getBlockId(), blockPlacementRule); } public BlockPlacementRule getBlockPlacementRule(short blockId) { - Block block = Block.getBlockFromId(blockId); - return this.placementRules.get(block); + Block block = Block.getBlockFromId(blockId); // Convert block alternative + blockId = block.getBlockId(); + return this.placementRules.get(blockId); } public CustomBlock getBlock(String identifier) { diff --git a/src/main/java/fr/themode/minestom/instance/block/rule/BlockPlacementRule.java b/src/main/java/fr/themode/minestom/instance/block/rule/BlockPlacementRule.java index d08193bde..8cac9c69c 100644 --- a/src/main/java/fr/themode/minestom/instance/block/rule/BlockPlacementRule.java +++ b/src/main/java/fr/themode/minestom/instance/block/rule/BlockPlacementRule.java @@ -6,15 +6,19 @@ import fr.themode.minestom.utils.BlockPosition; public abstract class BlockPlacementRule { - private Block block; + private short blockId; + + public BlockPlacementRule(short blockId) { + this.blockId = blockId; + } public BlockPlacementRule(Block block) { - this.block = block; + this(block.getBlockId()); } public abstract short blockRefresh(Instance instance, BlockPosition blockPosition); - public Block getBlock() { - return block; + public short getBlockId() { + return blockId; } } diff --git a/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java b/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java index 301517280..e8b6cf8e1 100644 --- a/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java +++ b/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java @@ -7,7 +7,6 @@ import fr.themode.minestom.utils.BlockPosition; public class RedstonePlacementRule extends BlockPlacementRule { - public RedstonePlacementRule() { super(Block.REDSTONE_WIRE); } @@ -18,6 +17,11 @@ public class RedstonePlacementRule extends BlockPlacementRule { int y = blockPosition.getY(); int z = blockPosition.getZ(); + if (isAir(instance, x, y - 1, z)) { + return Block.AIR.getBlockId(); + } + + String east = "none"; String north = "none"; String power = "0"; @@ -67,4 +71,9 @@ public class RedstonePlacementRule extends BlockPlacementRule { return Block.getBlockFromId(blockId) == Block.REDSTONE_WIRE; } + private boolean isAir(Instance instance, int x, int y, int z) { + short blockId = instance.getBlockId(x, y, z); + return Block.getBlockFromId(blockId) == Block.AIR; + } + } diff --git a/src/main/java/fr/themode/minestom/net/ConnectionManager.java b/src/main/java/fr/themode/minestom/net/ConnectionManager.java index fe61631b9..de62ec54b 100644 --- a/src/main/java/fr/themode/minestom/net/ConnectionManager.java +++ b/src/main/java/fr/themode/minestom/net/ConnectionManager.java @@ -2,7 +2,7 @@ package fr.themode.minestom.net; import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.player.PlayerConnection; -import fr.themode.minestom.ping.ResponseData; +import fr.themode.minestom.ping.ResponseDataConsumer; import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; @@ -14,7 +14,7 @@ public class ConnectionManager { private Set players = new CopyOnWriteArraySet<>(); private Map connectionPlayerMap = Collections.synchronizedMap(new HashMap<>()); - private Consumer responseDataConsumer; + private ResponseDataConsumer responseDataConsumer; private Consumer playerInitialization; public Player getPlayer(PlayerConnection connection) { @@ -49,11 +49,11 @@ public class ConnectionManager { broadcastMessage(message, null); } - public Consumer getResponseDataConsumer() { + public ResponseDataConsumer getResponseDataConsumer() { return responseDataConsumer; } - public void setResponseDataConsumer(Consumer responseDataConsumer) { + public void setResponseDataConsumer(ResponseDataConsumer responseDataConsumer) { this.responseDataConsumer = responseDataConsumer; } 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 0cdfe5b06..5cfd7206a 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 @@ -5,7 +5,8 @@ import fr.themode.minestom.net.packet.client.ClientPacket; public class ClientPacketsHandler { - private static final int SIZE = 0xFF; + // Max packet id + private static final int SIZE = 0x2E; private ConstructorAccess[] constructorAccesses = new ConstructorAccess[SIZE]; diff --git a/src/main/java/fr/themode/minestom/net/packet/client/status/StatusRequestPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/status/StatusRequestPacket.java index c0a1c43b4..23f798c50 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/status/StatusRequestPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/status/StatusRequestPacket.java @@ -7,18 +7,17 @@ import fr.themode.minestom.net.packet.client.ClientPreplayPacket; import fr.themode.minestom.net.packet.server.handshake.ResponsePacket; import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.ping.ResponseData; - -import java.util.function.Consumer; +import fr.themode.minestom.ping.ResponseDataConsumer; public class StatusRequestPacket implements ClientPreplayPacket { @Override public void process(PlayerConnection connection, ConnectionManager connectionManager) { - Consumer consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer(); + ResponseDataConsumer consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer(); ResponseData responseData = new ResponseData(); if (responseData == null) throw new NullPointerException("You need to register a ResponseDataConsumer"); - consumer.accept(responseData); + consumer.accept(connection, responseData); ResponsePacket responsePacket = new ResponsePacket(); responsePacket.jsonResponse = responseData.build().toString(); diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/ParticlePacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/ParticlePacket.java index a449b09f9..14ed60390 100644 --- a/src/main/java/fr/themode/minestom/net/packet/server/play/ParticlePacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/ParticlePacket.java @@ -4,6 +4,8 @@ import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacketIdentifier; +import java.util.function.Consumer; + public class ParticlePacket implements ServerPacket { public int particleId; @@ -13,7 +15,7 @@ public class ParticlePacket implements ServerPacket { public float particleData; public int particleCount; - public int blockId; + public Consumer dataConsumer; @Override public void write(PacketWriter writer) { @@ -27,8 +29,10 @@ public class ParticlePacket implements ServerPacket { writer.writeFloat(offsetZ); writer.writeFloat(particleData); writer.writeInt(particleCount); - if (particleId == 3) - writer.writeVarInt(blockId); + + if (dataConsumer != null) { + dataConsumer.accept(writer); + } } @Override diff --git a/src/main/java/fr/themode/minestom/net/player/PlayerConnection.java b/src/main/java/fr/themode/minestom/net/player/PlayerConnection.java index 21984ff6d..8c2a9b2f0 100644 --- a/src/main/java/fr/themode/minestom/net/player/PlayerConnection.java +++ b/src/main/java/fr/themode/minestom/net/player/PlayerConnection.java @@ -6,6 +6,9 @@ import fr.themode.minestom.net.ConnectionState; import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.utils.PacketUtils; +import java.io.IOException; +import java.net.SocketAddress; + public class PlayerConnection { private Client client; @@ -36,6 +39,15 @@ public class PlayerConnection { client.flush(); } + public SocketAddress getRemoteAddress() { + try { + return client.getChannel().getRemoteAddress(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + public Client getClient() { return client; } diff --git a/src/main/java/fr/themode/minestom/particle/Particle.java b/src/main/java/fr/themode/minestom/particle/Particle.java new file mode 100644 index 000000000..9337979a6 --- /dev/null +++ b/src/main/java/fr/themode/minestom/particle/Particle.java @@ -0,0 +1,87 @@ +package fr.themode.minestom.particle; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +public enum Particle { + + AMBIENT_ENTITY_EFFECT, + ANGRY_VILLAGER, + BARRIER, + BLOCK, + BUBBLE, + CLOUD, + CRIT, + DAMAGE_INDICATOR, + DRAGON_BREATH, + DRIPPING_LAVA, + FALLING_LAVA, + LANDING_LAVA, + DRIPPING_WATER, + FALLING_WATER, + DUST, + EFFECT, + ELDER_GUARDIAN, + ENCHANTED_HIT, + ENCHANT, + END_ROD, + ENTITY_EFFECT, + EXPLOSION_EMITTER, + EXPLOSION, + FALLING_DUST, + FIREWORK, + FISHING, + FLAME, + FLASH, + HAPPY_VILLAGER, + COMPOSTER, + HEART, + INSTANT_EFFECT, + ITEM, + ITEM_SLIME, + ITEM_SNOWBALL, + LARGE_SMOKE, + LAVA, + MYCELIUM, + NOTE, + POOF, + PORTAL, + RAIN, + SMOKE, + SNEEZE, + SPIT, + SQUID_INK, + SWEEP_ATTACK, + TOTEM_OF_UNDYING, + UNDERWATER, + SPLASH, + WITCH, + BUBBLE_POP, + CURRENT_DOWN, + BUBBLE_COLUMN_UP, + NAUTILUS, + DOLPHIN, + CAMPFIRE_COSY_SMOKE, + CAMPFIRE_SIGNAL_SMOKE, + DRIPPING_HONEY, + FALLING_HONEY, + LANDING_HONEY, + FALLING_NECTAR; + + private static Int2ObjectOpenHashMap map = new Int2ObjectOpenHashMap(); + + private int id; + + public static Particle fromId(int id) { + return map.get(id); + } + + public void setIdentifier(int id) { + this.id = id; + + map.put(id, this); + } + + public int getId() { + return id; + } +} diff --git a/src/main/java/fr/themode/minestom/particle/ParticleCreator.java b/src/main/java/fr/themode/minestom/particle/ParticleCreator.java new file mode 100644 index 000000000..0bf1757e8 --- /dev/null +++ b/src/main/java/fr/themode/minestom/particle/ParticleCreator.java @@ -0,0 +1,43 @@ +package fr.themode.minestom.particle; + +import fr.themode.minestom.net.packet.PacketWriter; +import fr.themode.minestom.net.packet.server.play.ParticlePacket; + +import java.util.function.Consumer; + +public class ParticleCreator { + + public static ParticlePacket createParticlePacket(Particle particle, boolean distance, + double x, double y, double z, + float offsetX, float offsetY, float offsetZ, + float particleData, int count, Consumer dataWriter) { + ParticlePacket particlePacket = new ParticlePacket(); + particlePacket.particleId = particle.getId(); + particlePacket.longDistance = distance; + + particlePacket.x = x; + particlePacket.y = y; + particlePacket.z = z; + + particlePacket.offsetX = offsetX; + particlePacket.offsetY = offsetY; + particlePacket.offsetZ = offsetZ; + + particlePacket.particleData = particleData; + particlePacket.particleCount = count; + particlePacket.dataConsumer = dataWriter; + + return particlePacket; + } + + public static ParticlePacket createParticlePacket(Particle particle, + double x, double y, double z, + float offsetX, float offsetY, float offsetZ, + int count) { + return createParticlePacket(particle, false, + x, y, z, + offsetX, offsetY, offsetZ, + 0, count, null); + } + +} diff --git a/src/main/java/fr/themode/minestom/ping/ResponseDataConsumer.java b/src/main/java/fr/themode/minestom/ping/ResponseDataConsumer.java new file mode 100644 index 000000000..62ecf3ab5 --- /dev/null +++ b/src/main/java/fr/themode/minestom/ping/ResponseDataConsumer.java @@ -0,0 +1,10 @@ +package fr.themode.minestom.ping; + +import fr.themode.minestom.net.player.PlayerConnection; + +@FunctionalInterface +public interface ResponseDataConsumer { + + void accept(PlayerConnection playerConnection, ResponseData responseData); + +} diff --git a/src/main/java/fr/themode/minestom/registry/RegistryMain.java b/src/main/java/fr/themode/minestom/registry/RegistryMain.java index 67780a38e..3101dc94c 100644 --- a/src/main/java/fr/themode/minestom/registry/RegistryMain.java +++ b/src/main/java/fr/themode/minestom/registry/RegistryMain.java @@ -7,6 +7,7 @@ import com.google.gson.JsonObject; import fr.themode.minestom.entity.EntityType; import fr.themode.minestom.instance.block.Block; import fr.themode.minestom.item.Material; +import fr.themode.minestom.particle.Particle; import fr.themode.minestom.sound.Sound; import java.io.BufferedReader; @@ -23,16 +24,19 @@ public class RegistryMain { public static final String ITEMS_PATH = "registry/registries.json"; public static final String ENTITIES_PATH = "registry/registries.json"; public static final String SOUNDS_PATH = "registry/registries.json"; + public static final String PARTICLES_PATH = "registry/registries.json"; public static void main(String[] args) { List blocks = parseBlocks(BLOCKS_PATH); List items = parseItems(ITEMS_PATH); List entities = parseEntities(ENTITIES_PATH); List sounds = parseSounds(SOUNDS_PATH); + List particles = parseParticles(PARTICLES_PATH); //writeBlocksClass(blocks); //writeItemsClass(items); //writeEntitiesClass(entities); - writeSoundsClass(sounds); + //writeSoundsClass(sounds); + writeParticlesClass(particles); } public static void registerBlocks() { @@ -90,6 +94,15 @@ public class RegistryMain { } } + public static void registerParticles() { + List registryParticles = parseParticles(PARTICLES_PATH); + + for (RegistryParticle registryParticle : registryParticles) { + Particle particle = Particle.valueOf(registryParticle.name); + particle.setIdentifier(registryParticle.id); + } + } + private static void writeBlocksClass(List blocks) { for (RegistryBlock registryBlock : blocks) { String line = registryBlock.name + ","; @@ -119,6 +132,13 @@ public class RegistryMain { } } + private static void writeParticlesClass(List particles) { + for (RegistryParticle registryParticle : particles) { + String line = registryParticle.name + ","; + System.out.println(line); + } + } + private static List parseBlocks(String path) { List blocks = new ArrayList<>(); @@ -279,4 +299,34 @@ public class RegistryMain { return registrySounds; } + private static List parseParticles(String path) { + List registryParticles = new ArrayList<>(); + + BufferedReader bufferedReader = null; + try { + bufferedReader = new BufferedReader(new FileReader(path)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + Gson gson = new Gson(); + JsonObject obj = gson.fromJson(bufferedReader, JsonObject.class); + + JsonObject itemsObject = obj.getAsJsonObject("minecraft:particle_type"); + JsonObject entriesObject = itemsObject.getAsJsonObject("entries"); + + Set> entriesEntries = entriesObject.entrySet();//will return members of your object + for (Map.Entry entryEntry : entriesEntries) { + RegistryParticle registryParticle = new RegistryParticle(); + registryParticles.add(registryParticle); + String item = entryEntry.getKey(); + String itemName = item.toUpperCase().replace("MINECRAFT:", "").replace(".", "_"); + registryParticle.name = itemName; + short id = entryEntry.getValue().getAsJsonObject().get("protocol_id").getAsShort(); + registryParticle.id = id; + } + + return registryParticles; + } + } diff --git a/src/main/java/fr/themode/minestom/registry/RegistryParticle.java b/src/main/java/fr/themode/minestom/registry/RegistryParticle.java new file mode 100644 index 000000000..ac66b6664 --- /dev/null +++ b/src/main/java/fr/themode/minestom/registry/RegistryParticle.java @@ -0,0 +1,8 @@ +package fr.themode.minestom.registry; + +public class RegistryParticle { + + protected String name; + protected int id; + +} diff --git a/src/main/java/fr/themode/minestom/utils/NbtReaderUtils.java b/src/main/java/fr/themode/minestom/utils/NbtReaderUtils.java index 53a8629f5..2c1508018 100644 --- a/src/main/java/fr/themode/minestom/utils/NbtReaderUtils.java +++ b/src/main/java/fr/themode/minestom/utils/NbtReaderUtils.java @@ -13,6 +13,7 @@ public class NbtReaderUtils { public static void readItemStackNBT(PacketReader reader, Consumer consumer, ItemStack item) { reader.readByte(typeId -> { + //System.out.println("DEBUG TYPE: " + typeId); switch (typeId) { case 0x00: // TAG_End // End of item NBT @@ -37,6 +38,15 @@ public class NbtReaderUtils { case 0x03: // TAG_Int reader.readShortSizedString((name, length) -> { + // Damage + if (name.equals("Damage")) { + reader.readInteger(damage -> { + //item.setDamage(damage); + // TODO short vs int damage + readItemStackNBT(reader, consumer, item); + }); + } + // Unbreakable if (name.equals("Unbreakable")) { reader.readInteger(value -> { @@ -64,6 +74,14 @@ public class NbtReaderUtils { break; case 0x09: // TAG_List + reader.readShortSizedString((name, length) -> { + + if (name.equals("StoredEnchantments")) { + // TODO + } + + }); + break; case 0x0A: // TAG_Compound