Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-16 13:00:12 +01:00
Skip extra buf copying entirely if wrapper had no changes
Dieser Commit ist enthalten in:
Ursprung
76db43cab3
Commit
77f0826ec8
@ -61,6 +61,15 @@ public class VarIntType extends Type<Integer> implements TypeConverter<Integer>
|
|||||||
buffer.writeByte(value);
|
buffer.writeByte(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int varIntLength(int value) {
|
||||||
|
int length = 1;
|
||||||
|
while ((value & MULTI_BYTE_BITS) != 0) {
|
||||||
|
length++;
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use {@link #readPrimitive(ByteBuf)} for manual reading to avoid wrapping
|
* @deprecated use {@link #readPrimitive(ByteBuf)} for manual reading to avoid wrapping
|
||||||
*/
|
*/
|
||||||
|
@ -29,8 +29,8 @@ import com.viaversion.viaversion.api.protocol.Protocol;
|
|||||||
import com.viaversion.viaversion.api.protocol.packet.Direction;
|
import com.viaversion.viaversion.api.protocol.packet.Direction;
|
||||||
import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
|
import com.viaversion.viaversion.api.protocol.packet.PacketTracker;
|
||||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
|
||||||
import com.viaversion.viaversion.api.type.Types;
|
import com.viaversion.viaversion.api.type.Types;
|
||||||
|
import com.viaversion.viaversion.api.type.types.VarIntType;
|
||||||
import com.viaversion.viaversion.exception.CancelException;
|
import com.viaversion.viaversion.exception.CancelException;
|
||||||
import com.viaversion.viaversion.exception.InformativeException;
|
import com.viaversion.viaversion.exception.InformativeException;
|
||||||
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
|
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
|
||||||
@ -335,7 +335,7 @@ public class UserConnectionImpl implements UserConnection {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = Types.VAR_INT.readPrimitive(buf);
|
final int id = Types.VAR_INT.readPrimitive(buf);
|
||||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||||
if (!passthroughTokens.remove(Types.UUID.read(buf))) {
|
if (!passthroughTokens.remove(Types.UUID.read(buf))) {
|
||||||
throw new IllegalArgumentException("Invalid token");
|
throw new IllegalArgumentException("Invalid token");
|
||||||
@ -343,29 +343,43 @@ public class UserConnectionImpl implements UserConnection {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketWrapperImpl wrapper = new PacketWrapperImpl(id, buf, this);
|
final int valuesReaderIndex = buf.readerIndex();
|
||||||
State state = protocolInfo.getState(direction);
|
final PacketWrapperImpl wrapper = new PacketWrapperImpl(id, buf, this);
|
||||||
try {
|
try {
|
||||||
protocolInfo.getPipeline().transform(direction, state, wrapper);
|
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(direction), wrapper);
|
||||||
} catch (CancelException ex) {
|
} catch (final CancelException ex) {
|
||||||
throw cancelSupplier.apply(ex);
|
throw cancelSupplier.apply(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToBuffer(wrapper, buf);
|
writeToBuffer(wrapper, buf, id, valuesReaderIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToBuffer(final PacketWrapperImpl wrapper, final ByteBuf buf) {
|
private void writeToBuffer(final PacketWrapperImpl wrapper, final ByteBuf buf, final int originalId, final int originalReaderIndex) {
|
||||||
|
final int remainingBytes = buf.readableBytes();
|
||||||
|
if (buf.readerIndex() == originalReaderIndex && wrapper.areStoredPacketValuesEmpty()) {
|
||||||
|
if (wrapper.getId() == originalId) {
|
||||||
|
// No changes needed; just set the reader and writer indexes and we're done
|
||||||
|
buf.setIndex(0, originalReaderIndex + remainingBytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (VarIntType.varIntLength(wrapper.getId()) == VarIntType.varIntLength(originalId)) {
|
||||||
|
// If the var int encoded length is the same, simply replace the id at the head
|
||||||
|
buf.setIndex(0, 0);
|
||||||
|
Types.VAR_INT.writePrimitive(buf, wrapper.getId());
|
||||||
|
buf.writerIndex(originalReaderIndex + remainingBytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Instead of allocating a possible unnecessarily large buffer to write the wrapper contents to,
|
// Instead of allocating a possible unnecessarily large buffer to write the wrapper contents to,
|
||||||
// only allocate the remaining bytes and write the rest to the original buf's head directly.
|
// only allocate the remaining bytes and write the rest to the original buf's head directly.
|
||||||
final int remainingBytes = buf.readableBytes();
|
|
||||||
final ByteBuf remainingBuf = buf.alloc().buffer(remainingBytes);
|
final ByteBuf remainingBuf = buf.alloc().buffer(remainingBytes);
|
||||||
try {
|
try {
|
||||||
// Copy before modifying the buffer
|
// Copy before modifying the buffer
|
||||||
remainingBuf.writeBytes(buf, remainingBytes);
|
remainingBuf.writeBytes(buf, remainingBytes);
|
||||||
|
|
||||||
// Reset indexes, write wrapper contents, then the unread bytes
|
// Reset indexes, write wrapper contents, then the unread bytes
|
||||||
buf.readerIndex(0);
|
buf.setIndex(0, 0);
|
||||||
buf.writerIndex(0);
|
|
||||||
wrapper.writeProcessedValues(buf);
|
wrapper.writeProcessedValues(buf);
|
||||||
buf.writeBytes(remainingBuf);
|
buf.writeBytes(remainingBuf);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -228,6 +228,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean areStoredPacketValuesEmpty() {
|
||||||
|
// Check for read/added packet values, not the input buffer
|
||||||
|
return packetValues.isEmpty() && readableObjects.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public void writeProcessedValues(ByteBuf buffer) throws InformativeException {
|
public void writeProcessedValues(ByteBuf buffer) throws InformativeException {
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
Types.VAR_INT.writePrimitive(buffer, id);
|
Types.VAR_INT.writePrimitive(buffer, id);
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren