diff --git a/src/main/java/net/minestom/server/network/NetworkBuffer.java b/src/main/java/net/minestom/server/network/NetworkBuffer.java index 57d2329ea..c7e827a04 100644 --- a/src/main/java/net/minestom/server/network/NetworkBuffer.java +++ b/src/main/java/net/minestom/server/network/NetworkBuffer.java @@ -256,7 +256,8 @@ public final class NetworkBuffer { void ensureSize(int length) { if (!resizable) return; if (nioBuffer.capacity() < writeIndex + length) { - ByteBuffer newBuffer = ByteBuffer.allocateDirect(nioBuffer.capacity() * 2); + final int newCapacity = Math.max(nioBuffer.capacity() * 2, writeIndex + length); + ByteBuffer newBuffer = ByteBuffer.allocateDirect(newCapacity); nioBuffer.position(0); newBuffer.put(nioBuffer); nioBuffer = newBuffer.clear(); diff --git a/src/main/java/net/minestom/server/network/NetworkBufferTypes.java b/src/main/java/net/minestom/server/network/NetworkBufferTypes.java index f84e68858..20b60bc65 100644 --- a/src/main/java/net/minestom/server/network/NetworkBufferTypes.java +++ b/src/main/java/net/minestom/server/network/NetworkBufferTypes.java @@ -114,28 +114,30 @@ final class NetworkBufferTypes { (buffer, boxed) -> { final int value = boxed; final int index = buffer.writeIndex(); - var nio = buffer.nioBuffer; if ((value & (0xFFFFFFFF << 7)) == 0) { buffer.ensureSize(1); - nio.put(index, (byte) value); + buffer.nioBuffer.put(index, (byte) value); return 1; } else if ((value & (0xFFFFFFFF << 14)) == 0) { buffer.ensureSize(2); - nio.putShort(index, (short) ((value & 0x7F | 0x80) << 8 | (value >>> 7))); + buffer.nioBuffer.putShort(index, (short) ((value & 0x7F | 0x80) << 8 | (value >>> 7))); return 2; } else if ((value & (0xFFFFFFFF << 21)) == 0) { buffer.ensureSize(3); + var nio = buffer.nioBuffer; nio.put(index, (byte) (value & 0x7F | 0x80)); nio.put(index + 1, (byte) ((value >>> 7) & 0x7F | 0x80)); nio.put(index + 2, (byte) (value >>> 14)); return 3; } else if ((value & (0xFFFFFFFF << 28)) == 0) { buffer.ensureSize(4); + var nio = buffer.nioBuffer; nio.putInt(index, (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16) | ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21)); return 4; } else { buffer.ensureSize(5); + var nio = buffer.nioBuffer; nio.putInt(index, (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16 | ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80)); nio.put(index + 4, (byte) (value >>> 28)); diff --git a/src/test/java/net/minestom/server/network/NetworkBufferTest.java b/src/test/java/net/minestom/server/network/NetworkBufferTest.java index ae0be9437..107e1c53a 100644 --- a/src/test/java/net/minestom/server/network/NetworkBufferTest.java +++ b/src/test/java/net/minestom/server/network/NetworkBufferTest.java @@ -17,6 +17,30 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class NetworkBufferTest { + @Test + public void resize() { + var buffer = new NetworkBuffer(6); + buffer.write(INT, 6); + assertEquals(4, buffer.writeIndex()); + + buffer.write(INT, 7); + assertEquals(8, buffer.writeIndex()); + + assertEquals(6, buffer.read(INT)); + assertEquals(7, buffer.read(INT)); + + // Test one-off length + buffer = new NetworkBuffer(1); + buffer.write(BYTE, (byte) 3); + assertEquals(1, buffer.writeIndex()); + + buffer.write(BYTE, (byte) 4); + assertEquals(2, buffer.writeIndex()); + + assertEquals((byte) 3, buffer.read(BYTE)); + assertEquals((byte) 4, buffer.read(BYTE)); + } + @Test public void readableBytes() { var buffer = new NetworkBuffer(); @@ -264,6 +288,20 @@ public class NetworkBufferTest { buffer.copyTo(0, bytes, 0, bytes.length); assertArrayEquals(expected, bytes, "Invalid bytes: " + Arrays.toString(expected) + " != " + Arrays.toString(bytes)); } + + // Ensure resize support + { + var tmp = new NetworkBuffer(0); + action.write(tmp, type, value); + assertEquals(0, tmp.readIndex()); + if (expected != null) assertEquals(expected.length, tmp.writeIndex()); + + var tmpRead = action.read(tmp, type); + + assertEquals(value, tmpRead); + if (expected != null) assertEquals(expected.length, tmp.readIndex(), "Invalid read index"); + if (expected != null) assertEquals(expected.length, tmp.writeIndex()); + } } static void assertBufferType(NetworkBuffer.@NotNull Type type, @NotNull T value, byte @Nullable [] expected) {