mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-28 20:18:10 +01:00
PacketUtils improvement with initial capacity packet + optimize the ChunkDataPacket
This commit is contained in:
parent
f2222cfaf2
commit
7ea06cc70b
@ -86,8 +86,6 @@ dependencies {
|
||||
api 'io.netty:netty-codec:4.1.51.Final'
|
||||
implementation 'io.netty:netty-transport-native-epoll:4.1.51.Final:linux-x86_64'
|
||||
|
||||
api 'com.github.jhg023:Pbbl:1.0.2'
|
||||
|
||||
// https://mvnrepository.com/artifact/it.unimi.dsi/fastutil
|
||||
api 'it.unimi.dsi:fastutil:8.4.1'
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
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,8 +13,6 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.buffer.BufferUtils;
|
||||
import net.minestom.server.utils.buffer.BufferWrapper;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
@ -47,7 +47,7 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
writer.writeBoolean(fullChunk);
|
||||
|
||||
int mask = 0;
|
||||
BufferWrapper blocks = BufferUtils.getBuffer(MAX_BUFFER_SIZE);
|
||||
ByteBuf blocks = Unpooled.buffer(MAX_BUFFER_SIZE);
|
||||
for (byte i = 0; i < CHUNK_SECTION_COUNT; i++) {
|
||||
if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) {
|
||||
short[] section = getSection(i);
|
||||
@ -91,8 +91,8 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
}
|
||||
|
||||
// Data
|
||||
writer.writeVarInt(blocks.getSize());
|
||||
writer.writeBufferAndFree(blocks);
|
||||
writer.writeVarInt(blocks.writerIndex());
|
||||
writer.getBuffer().writeBytes(blocks);
|
||||
|
||||
// Block entities
|
||||
writer.writeVarInt(blockEntities.size());
|
||||
|
@ -21,11 +21,10 @@ public final class PacketUtils {
|
||||
* @param packet the packet to write into {@code buf}
|
||||
*/
|
||||
public static void writePacket(ByteBuf buf, ServerPacket packet) {
|
||||
BinaryWriter writer = new BinaryWriter();
|
||||
|
||||
Utils.writeVarIntBuf(buf, packet.getId());
|
||||
packet.write(writer);
|
||||
buf.writeBytes(writer.toByteArray());
|
||||
final ByteBuf packetBuffer = getPacketBuffer(packet);
|
||||
|
||||
writePacket(buf, packetBuffer, packet.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,11 +34,40 @@ public final class PacketUtils {
|
||||
* @return a {@link ByteBuf} containing {@code packet}
|
||||
*/
|
||||
public static ByteBuf writePacket(ServerPacket packet) {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
final ByteBuf packetBuffer = getPacketBuffer(packet);
|
||||
|
||||
writePacket(buffer, packet);
|
||||
// Add 5 for the packet id and for the packet size
|
||||
final int size = packetBuffer.writerIndex() + 5 + 5;
|
||||
ByteBuf buffer = Unpooled.buffer(size);
|
||||
|
||||
writePacket(buffer, packetBuffer, packet.getId());
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a packet buffer into {@code buf}
|
||||
*
|
||||
* @param buf the buffer which will receive the packet id/data
|
||||
* @param packetBuffer the buffer containing the raw packet data
|
||||
* @param packetId the packet id
|
||||
*/
|
||||
private static void writePacket(ByteBuf buf, ByteBuf packetBuffer, int packetId) {
|
||||
Utils.writeVarIntBuf(buf, packetId);
|
||||
buf.writeBytes(packetBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buffer representing the raw packet data
|
||||
*
|
||||
* @param packet the packet to write
|
||||
* @return the {@link ByteBuf} containing the raw packet data
|
||||
*/
|
||||
private static ByteBuf getPacketBuffer(ServerPacket packet) {
|
||||
BinaryWriter writer = new BinaryWriter();
|
||||
packet.write(writer);
|
||||
|
||||
return writer.getBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package net.minestom.server.utils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.buffer.BufferWrapper;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
@ -30,17 +29,6 @@ public final class Utils {
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
public static void writeVarIntBuffer(BufferWrapper buffer, int value) {
|
||||
do {
|
||||
byte temp = (byte) (value & 0b01111111);
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buffer.putByte(temp);
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
public static void writeVarInt(BinaryWriter writer, int value) {
|
||||
do {
|
||||
byte temp = (byte) (value & 0b01111111);
|
||||
@ -103,14 +91,14 @@ public final class Utils {
|
||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||
0, 5};
|
||||
|
||||
public static void writeBlocks(BufferWrapper buffer, short[] blocksId, int bitsPerEntry) {
|
||||
public static void writeBlocks(ByteBuf buffer, short[] blocksId, int bitsPerEntry) {
|
||||
short count = 0;
|
||||
for (short id : blocksId)
|
||||
if (id != 0)
|
||||
count++;
|
||||
|
||||
buffer.putShort(count);
|
||||
buffer.putByte((byte) bitsPerEntry);
|
||||
buffer.writeShort(count);
|
||||
buffer.writeByte((byte) bitsPerEntry);
|
||||
int[] blocksData = new int[Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SIZE_Z];
|
||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
@ -121,28 +109,28 @@ public final class Utils {
|
||||
}
|
||||
}
|
||||
}
|
||||
long[] data = encodeBlocks(blocksData, bitsPerEntry);
|
||||
buffer.putVarInt(data.length);
|
||||
final long[] data = encodeBlocks(blocksData, bitsPerEntry);
|
||||
writeVarIntBuf(buffer, data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
buffer.putLong(data[i]);
|
||||
buffer.writeLong(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static long[] encodeBlocks(int[] blocks, int bitsPerEntry) {
|
||||
long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
char valuesPerLong = (char) (64 / bitsPerEntry);
|
||||
int magicIndex = 3 * (valuesPerLong - 1);
|
||||
long divideMul = Integer.toUnsignedLong(MAGIC[magicIndex]);
|
||||
long divideAdd = Integer.toUnsignedLong(MAGIC[magicIndex + 1]);
|
||||
int divideShift = MAGIC[magicIndex + 2];
|
||||
int size = (blocks.length + valuesPerLong - 1) / valuesPerLong;
|
||||
final long maxEntryValue = (1L << bitsPerEntry) - 1;
|
||||
final char valuesPerLong = (char) (64 / bitsPerEntry);
|
||||
final int magicIndex = 3 * (valuesPerLong - 1);
|
||||
final long divideMul = Integer.toUnsignedLong(MAGIC[magicIndex]);
|
||||
final long divideAdd = Integer.toUnsignedLong(MAGIC[magicIndex + 1]);
|
||||
final int divideShift = MAGIC[magicIndex + 2];
|
||||
final int size = (blocks.length + valuesPerLong - 1) / valuesPerLong;
|
||||
|
||||
long[] data = new long[size];
|
||||
|
||||
for (int i = 0; i < blocks.length; i++) {
|
||||
long value = blocks[i];
|
||||
int cellIndex = (int) (i * divideMul + divideAdd >> 32L >> divideShift);
|
||||
int bitIndex = (i - cellIndex * valuesPerLong) * bitsPerEntry;
|
||||
final long value = blocks[i];
|
||||
final int cellIndex = (int) (i * divideMul + divideAdd >> 32L >> divideShift);
|
||||
final int bitIndex = (i - cellIndex * valuesPerLong) * bitsPerEntry;
|
||||
data[cellIndex] = data[cellIndex] & ~(maxEntryValue << bitIndex) | (value & maxEntryValue) << bitIndex;
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,11 @@ import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.NBTUtils;
|
||||
import net.minestom.server.utils.SerializerUtils;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import net.minestom.server.utils.buffer.BufferWrapper;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
@ -210,15 +208,6 @@ public class BinaryWriter extends OutputStream {
|
||||
consumer.accept(this);
|
||||
}
|
||||
|
||||
public void writeBufferAndFree(BufferWrapper buffer) {
|
||||
ByteBuffer byteBuffer = buffer.getByteBuffer();
|
||||
final int size = buffer.getSize();
|
||||
byte[] cache = new byte[size];
|
||||
byteBuffer.position(0).get(cache, 0, size);
|
||||
writeBytes(cache);
|
||||
buffer.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an {@link UUID}
|
||||
* It is done by writing both long, the most & least significant bits
|
||||
@ -263,6 +252,15 @@ public class BinaryWriter extends OutputStream {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw buffer used by this binary writer
|
||||
*
|
||||
* @return the raw buffer
|
||||
*/
|
||||
public ByteBuf getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
writeByte((byte) b);
|
||||
|
@ -1,22 +0,0 @@
|
||||
package net.minestom.server.utils.buffer;
|
||||
|
||||
import com.github.pbbl.heap.ByteBufferPool;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class BufferUtils {
|
||||
|
||||
private static final ByteBufferPool pool = new ByteBufferPool();
|
||||
|
||||
private BufferUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static BufferWrapper getBuffer(int size) {
|
||||
return new BufferWrapper(pool.take(size));
|
||||
}
|
||||
|
||||
protected static void giveBuffer(ByteBuffer byteBuffer) {
|
||||
pool.give(byteBuffer);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package net.minestom.server.utils.buffer;
|
||||
|
||||
import net.minestom.server.utils.Utils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BufferWrapper {
|
||||
|
||||
private final ByteBuffer byteBuffer;
|
||||
private int size;
|
||||
|
||||
protected BufferWrapper(ByteBuffer byteBuffer) {
|
||||
this.byteBuffer = byteBuffer;
|
||||
}
|
||||
|
||||
public void putByte(byte b) {
|
||||
this.byteBuffer.put(b);
|
||||
size += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void putShort(short s) {
|
||||
this.byteBuffer.putShort(s);
|
||||
size += Short.BYTES;
|
||||
}
|
||||
|
||||
public void putInt(int n) {
|
||||
this.byteBuffer.putInt(n);
|
||||
size += Integer.BYTES;
|
||||
}
|
||||
|
||||
public void putLong(long l) {
|
||||
this.byteBuffer.putLong(l);
|
||||
size += Long.BYTES;
|
||||
}
|
||||
|
||||
public void putVarInt(int n) {
|
||||
Utils.writeVarIntBuffer(this, n);
|
||||
size += Utils.getVarIntSize(n);
|
||||
}
|
||||
|
||||
public void putBytes(byte[] bytes) {
|
||||
this.byteBuffer.put(bytes);
|
||||
size += Byte.BYTES * bytes.length;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
BufferUtils.giveBuffer(getByteBuffer());
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return byteBuffer;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user