Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ public void setState(StateRegistry state) {
if (previousState == StateRegistry.PLAY
&& this.pendingConfigurationSwitch
&& this.association instanceof ConnectedPlayer) {
addPlayPacketQueueOutboundHandler();
addReconfigurationPlayPacketQueueHandler();
} else {
addPlayPacketQueueHandler();
}
Expand All @@ -419,7 +419,20 @@ public void addPlayPacketQueueHandler() {
if (this.channel.pipeline().get(Connections.PLAY_PACKET_QUEUE_INBOUND) == null) {
this.channel.pipeline().addAfter(Connections.MINECRAFT_DECODER, Connections.PLAY_PACKET_QUEUE_INBOUND,
new PlayPacketQueueInboundHandler(this.protocolVersion,
channel.pipeline().get(MinecraftDecoder.class).getDirection()));
channel.pipeline().get(MinecraftDecoder.class).getDirection(), false));
}
}

/**
* Adds the play packet queue handlers for a re-entrant configuration switch.
*/
public void addReconfigurationPlayPacketQueueHandler() {
addPlayPacketQueueOutboundHandler();

if (this.channel.pipeline().get(Connections.PLAY_PACKET_QUEUE_INBOUND) == null) {
this.channel.pipeline().addAfter(Connections.MINECRAFT_DECODER, Connections.PLAY_PACKET_QUEUE_INBOUND,
new PlayPacketQueueInboundHandler(this.protocolVersion,
channel.pipeline().get(MinecraftDecoder.class).getDirection(), true));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1384,8 +1384,8 @@ public void switchToConfigState() {
connection.write(StartUpdatePacket.INSTANCE);
connection.pendingConfigurationSwitch = true;
connection.getChannel().pipeline().get(MinecraftEncoder.class).setState(StateRegistry.CONFIG);
// Make sure we don't send any play packets to the player after update start
connection.addPlayPacketQueueOutboundHandler();
// Queue clientbound play packets, and drop stale serverbound ones, during reconfiguration
connection.addReconfigurationPlayPacketQueueHandler();
}, connection.eventLoop()).exceptionally((ex) -> {
logger.error("Error switching player connection to config state", ex);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
"Queue too big (greater than " + MAXIMUM_SIZE + " bytes)");

private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
private final boolean discardStaleInbound;

private final Queue<Object> queue = new ArrayDeque<>();
private int queueSize = 0;

Expand All @@ -57,8 +59,10 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
*
* @param version the protocol version
*/
public PlayPacketQueueInboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
public PlayPacketQueueInboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction,
boolean discardStaleInbound) {
this.registry = StateRegistry.CONFIG.getProtocolRegistry(direction, version);
this.discardStaleInbound = discardStaleInbound;
}

@Override
Expand All @@ -72,6 +76,13 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
}
}

if (this.discardStaleInbound) {
// Re-entering configuration: this play packet belongs to the previous play session and
// must not be replayed into the next one, so drop it rather than queueing it.
ReferenceCountUtil.release(msg);
return;
}

int length = 0;
if (msg instanceof ByteBuf) {
// keep track of raw packets
Expand Down