Fix packet duplicating at some points (#8566)

Due to the weakly consistent of ConcurrentLinkedQueue iterator, at some points, packet will be resent twice times or more, causing some weird behaviors (e.g. kicked for illegal movement since the same ClientboundPlayerPositionPacket was sent two times). This changes for the patch add a flag for marking if the packet was consumed to prevent such issue and ensure consistently of the packet queue.
This commit is contained in:
sandtechnology
2022-11-28 00:36:35 +08:00
parent 59d8df6cba
commit e9b9c0b332
2 changed files with 45 additions and 17 deletions

View File

@@ -129,6 +129,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return true;
}
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
Packet<?> packet = queued.packet;
if (!packet.isReady()) {
+ // Paper start - make only one flush call per sendPacketQueue() call
@@ -139,9 +141,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return false;
} else {
iterator.remove();
- this.sendPacket(packet, queued.listener);
+ this.sendPacket(packet, queued.listener, (!iterator.hasNext() && (needsFlush || this.canFlush)) ? Boolean.TRUE : Boolean.FALSE); // Paper - make only one flush call per sendPacketQueue() call
+ hasWrotePacket = true; // Paper - make only one flush call per sendPacketQueue() call
if (queued.tryMarkConsumed()) { // Paper - try to mark isConsumed flag for de-duplicating packet
- this.sendPacket(packet, queued.listener);
+ this.sendPacket(packet, queued.listener, (!iterator.hasNext() && (needsFlush || this.canFlush)) ? Boolean.TRUE : Boolean.FALSE); // Paper - make only one flush call per sendPacketQueue() call
+ hasWrotePacket = true; // Paper - make only one flush call per sendPacketQueue() call
}
}
}
return true;