Allow buffer index/length to be specified

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-11-02 03:08:36 +01:00
parent 0ba41ac88b
commit 970d4d2d9c
3 changed files with 35 additions and 25 deletions

View File

@ -230,13 +230,14 @@ public class PlayerSocketConnection extends PlayerConnection {
}
@ApiStatus.Internal
public void write(@NotNull ByteBuffer buffer) {
public void write(@NotNull ByteBuffer buffer, int index, int length) {
synchronized (bufferLock) {
if (encrypted) { // Encryption support
ByteBuffer output = PacketUtils.localBuffer();
try {
this.encryptCipher.update(buffer.duplicate(), output);
this.encryptCipher.update(buffer.slice(index,length), output);
buffer = output.flip();
index = 0;
} catch (ShortBufferException e) {
MinecraftServer.getExceptionManager().handleException(e);
return;
@ -245,22 +246,26 @@ public class PlayerSocketConnection extends PlayerConnection {
BinaryBuffer localBuffer = tickBuffer.getPlain();
final int capacity = localBuffer.capacity();
final int size = buffer.remaining();
if (size <= capacity) {
if (!localBuffer.canWrite(size)) localBuffer = updateLocalBuffer();
localBuffer.write(buffer);
if (length <= capacity) {
if (!localBuffer.canWrite(length)) localBuffer = updateLocalBuffer();
localBuffer.write(buffer, index, length);
} else {
final int bufferCount = size / capacity + 1;
final int bufferCount = length / capacity + 1;
for (int i = 0; i < bufferCount; i++) {
buffer.position(i * capacity);
buffer.limit(Math.min(size, buffer.position() + capacity));
if (!localBuffer.canWrite(buffer.remaining())) localBuffer = updateLocalBuffer();
localBuffer.write(buffer);
final int sliceStart = i * capacity;
final int sliceLength = Math.min(length, sliceStart + capacity) - sliceStart;
if (!localBuffer.canWrite(sliceLength)) localBuffer = updateLocalBuffer();
localBuffer.write(buffer, sliceStart, sliceLength);
}
}
}
}
@ApiStatus.Internal
public void write(@NotNull ByteBuffer buffer) {
write(buffer, buffer.position(), buffer.remaining());
}
private void writePacket(@NotNull ServerPacket packet) {
write(PacketUtils.createFramedPacket(packet, compressed));
}

View File

@ -248,7 +248,7 @@ public final class PacketUtils {
process(viewable);
for (Player viewer : viewable.getViewers()) {
if (!Objects.equals(player, viewer)) {
writeTo(viewer.getPlayerConnection(), framedPacket.position(0));
writeTo(viewer.getPlayerConnection(), framedPacket, 0, packetSize);
}
}
return;
@ -282,19 +282,23 @@ public final class PacketUtils {
for (int i = 0; i < pairs.size(); ++i) {
final long offsets = elements[i];
final int start = (int) (offsets >> 32);
if (start != lastWrite) writeTo(connection, buffer.view(lastWrite, start));
if (start != lastWrite) writeTo(connection, lastWrite, start - lastWrite);
lastWrite = (int) offsets; // End = last 32 bits
}
if (size != lastWrite) writeTo(connection, buffer.view(lastWrite, size));
if (size != lastWrite) writeTo(connection, lastWrite, size - lastWrite);
} else {
// Write all
writeTo(connection, buffer.view(0, size));
writeTo(connection, 0, size);
}
}
private static void writeTo(PlayerConnection connection, ByteBuffer buffer) {
if (connection instanceof PlayerSocketConnection) {
((PlayerSocketConnection) connection).write(buffer);
private void writeTo(PlayerConnection connection, int offset, int length) {
writeTo(connection, buffer.asByteBuffer(), offset, length);
}
private static void writeTo(PlayerConnection connection, ByteBuffer buffer, int offset, int length) {
if (connection instanceof PlayerSocketConnection socketConnection) {
socketConnection.write(buffer, offset, length);
return;
}
// TODO for non-socket connection

View File

@ -40,12 +40,13 @@ public final class BinaryBuffer {
return new BinaryBuffer(temp);
}
public void write(ByteBuffer buffer, int index, int length) {
this.nioBuffer.put(writerOffset, buffer, index, length);
this.writerOffset += length;
}
public void write(ByteBuffer buffer) {
final int start = buffer.position();
final int end = buffer.limit();
final int size = end - start;
this.nioBuffer.put(writerOffset, buffer, start, size);
this.writerOffset += size;
write(buffer, buffer.position(), buffer.remaining());
}
public void write(BinaryBuffer buffer) {
@ -135,8 +136,8 @@ public final class BinaryBuffer {
}
@ApiStatus.Internal
public ByteBuffer view(int position, int limit) {
return nioBuffer.limit(limit).position(position);
public ByteBuffer asByteBuffer() {
return nioBuffer;
}
public boolean writeChannel(WritableByteChannel channel) throws IOException {