diff --git a/prismarine-minecraft-data b/prismarine-minecraft-data index 472b3c041..33abb2dc5 160000 --- a/prismarine-minecraft-data +++ b/prismarine-minecraft-data @@ -1 +1 @@ -Subproject commit 472b3c041c58bd0a4397fb9144b1035682022cbe +Subproject commit 33abb2dc5dd350f05c8efbeb80835edf01056ff2 diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 0ef819fe4..11313f224 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -517,11 +517,6 @@ public class Player extends LivingEntity implements CommandSender { sendPacketToViewers(updatePacket); } - } else { - // Player did not move since last time - EntityMovementPacket entityMovementPacket = new EntityMovementPacket(); - entityMovementPacket.entityId = getEntityId(); - sendPacketToViewers(entityMovementPacket); } // Update sync data diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java index 0f68d6560..1be950606 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java @@ -1,7 +1,6 @@ package net.minestom.server.network.packet.server.play; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; @@ -11,6 +10,7 @@ import net.minestom.server.instance.palette.PaletteStorage; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.utils.BlockPosition; +import net.minestom.server.utils.BufUtils; import net.minestom.server.utils.Utils; import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.chunk.ChunkUtils; @@ -47,7 +47,7 @@ public class ChunkDataPacket implements ServerPacket { writer.writeBoolean(fullChunk); int mask = 0; - ByteBuf blocks = Unpooled.buffer(MAX_BUFFER_SIZE); + ByteBuf blocks = BufUtils.getBuffer(MAX_BUFFER_SIZE); for (byte i = 0; i < CHUNK_SECTION_COUNT; i++) { if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) { final long[] section = paletteStorage.getSectionBlocks()[i]; @@ -93,7 +93,8 @@ public class ChunkDataPacket implements ServerPacket { // Data writer.writeVarInt(blocks.writerIndex()); writer.getBuffer().writeBytes(blocks); - + blocks.release(); + // Block entities writer.writeVarInt(blockEntities.size()); diff --git a/src/main/java/net/minestom/server/utils/BufUtils.java b/src/main/java/net/minestom/server/utils/BufUtils.java new file mode 100644 index 000000000..7e622dcdd --- /dev/null +++ b/src/main/java/net/minestom/server/utils/BufUtils.java @@ -0,0 +1,34 @@ +package net.minestom.server.utils; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +public class BufUtils { + + private static final PooledByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT; + + public static ByteBuf getBuffer() { + return alloc.heapBuffer(); + } + + public static ByteBuf getBuffer(boolean io) { + return io ? alloc.ioBuffer() : alloc.heapBuffer(); + } + + public static ByteBuf getBuffer(int initialCapacity) { + return alloc.heapBuffer(initialCapacity); + } + + public static ByteBuf getBuffer(boolean io, int initialCapacity) { + return io ? alloc.ioBuffer(initialCapacity) : alloc.heapBuffer(initialCapacity); + } + + public static ByteBuf getBuffer(int initialCapacity, int maxCapacity) { + return alloc.heapBuffer(initialCapacity, maxCapacity); + } + + public static ByteBuf getBuffer(boolean io, int initialCapacity, int maxCapacity) { + return io ? alloc.ioBuffer(initialCapacity, maxCapacity) : alloc.heapBuffer(initialCapacity, maxCapacity); + } + +} diff --git a/src/main/java/net/minestom/server/utils/PacketUtils.java b/src/main/java/net/minestom/server/utils/PacketUtils.java index 8ccf4e377..ce61bd862 100644 --- a/src/main/java/net/minestom/server/utils/PacketUtils.java +++ b/src/main/java/net/minestom/server/utils/PacketUtils.java @@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import net.minestom.server.entity.Player; import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; @@ -85,9 +86,12 @@ public final class PacketUtils { */ @NotNull private static ByteBuf getPacketBuffer(@NotNull ServerPacket packet) { - BinaryWriter writer = new BinaryWriter(); + BinaryWriter writer; + if (packet.getId() == ServerPacketIdentifier.CHUNK_DATA) + writer = new BinaryWriter(BufUtils.getBuffer(true, 40_000)); + else + writer = new BinaryWriter(BufUtils.getBuffer(true)); packet.write(writer); - return writer.getBuffer(); } diff --git a/src/test/java/demo/Main.java b/src/test/java/demo/Main.java index e2047db6f..258368cbb 100644 --- a/src/test/java/demo/Main.java +++ b/src/test/java/demo/Main.java @@ -4,11 +4,13 @@ import demo.blocks.BurningTorchBlock; import demo.blocks.StoneBlock; import demo.blocks.UpdatableBlockDemo; import demo.commands.*; +import io.netty.util.ResourceLeakDetector; import net.minestom.server.MinecraftServer; import net.minestom.server.command.CommandManager; import net.minestom.server.extras.optifine.OptifineSupport; import net.minestom.server.instance.block.BlockManager; import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule; +import net.minestom.server.network.netty.NettyServer; import net.minestom.server.storage.StorageManager; import net.minestom.server.storage.systems.FileStorageSystem; import net.minestom.server.utils.time.TimeUnit; @@ -18,8 +20,14 @@ import net.minestom.server.utils.time.UpdateOption; public class Main { public static void main(String[] args) { + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID); + MinecraftServer minecraftServer = MinecraftServer.init(); + final NettyServer nettyServer = MinecraftServer.getNettyServer(); + nettyServer.setWriteLimit(500_000); + nettyServer.setWriteLimit(500_000); + BlockManager blockManager = MinecraftServer.getBlockManager(); blockManager.registerCustomBlock(new StoneBlock()); blockManager.registerCustomBlock(new UpdatableBlockDemo()); @@ -36,9 +44,7 @@ public class Main { commandManager.register(new DimensionCommand()); commandManager.register(new ShutdownCommand()); commandManager.register(new TeleportCommand()); - commandManager.register(new ReloadExtensionCommand()); - commandManager.register(new UnloadExtensionCommand()); - commandManager.register(new LoadExtensionCommand()); + commandManager.register(new PlayersCommand()); commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage("unknown command")); diff --git a/src/test/java/demo/commands/PlayersCommand.java b/src/test/java/demo/commands/PlayersCommand.java new file mode 100644 index 000000000..1ac7dbbfb --- /dev/null +++ b/src/test/java/demo/commands/PlayersCommand.java @@ -0,0 +1,37 @@ +package demo.commands; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.command.CommandSender; +import net.minestom.server.command.builder.Arguments; +import net.minestom.server.command.builder.Command; +import net.minestom.server.entity.Player; + +import java.util.Collection; +import java.util.stream.Collectors; + +public class PlayersCommand extends Command { + + public PlayersCommand() { + super("players"); + setDefaultExecutor(this::usage); + } + + private void usage(CommandSender sender, Arguments arguments) { + final Collection players = MinecraftServer.getConnectionManager().getOnlinePlayers(); + final int playerCount = players.size(); + sender.sendMessage(String.valueOf(playerCount)); + sender.sendMessage(""); + final int limit = 15; + if (playerCount <= limit) { + for (final Player player : players) { + sender.sendMessage(player.getUsername()); + } + } else { + for (final Player player : players.stream().limit(limit).collect(Collectors.toList())) { + sender.sendMessage(player.getUsername()); + } + sender.sendMessage("..."); + } + } + +}