Skip to content

Fix duplicate MONITOR listener invocation after async packet processing#3630

Open
Ingrim4 wants to merge 1 commit into
dmulloy2:masterfrom
Imprex-Development:fix/packet-delay
Open

Fix duplicate MONITOR listener invocation after async packet processing#3630
Ingrim4 wants to merge 1 commit into
dmulloy2:masterfrom
Imprex-Development:fix/packet-delay

Conversation

@Ingrim4
Copy link
Copy Markdown
Collaborator

@Ingrim4 Ingrim4 commented May 27, 2026

Summary

This PR fixes two related issues in packet handling after async processing:

  1. MONITOR listeners could be invoked twice when a packet was sent or received after async processing.
  2. Packets were delayed by one tick whenever any synchronous listener existed for the packet type, even when the only sync listeners were registered at MONITOR priority.

Problem

When async processing completes, ProtocolLib currently uses sendServerPacket(..., filters = false) or receiveClientPacket(..., filters = false) to continue packet handling.

Using filters = false skips normal packet listeners, but MONITOR listeners may still be invoked. Since the MONITOR listener has already run as the final synchronous listener before async processing, this causes it to run twice for the same packet.

There is also a packet ordering issue. If at least one synchronous listener is registered for a packet, the packet is delayed by one tick, even if the only synchronous listener is a MONITOR listener. Since MONITOR listeners are intended to be read-only and should not modify packets, delaying the packet in that case is unnecessary.

In some cases, this delay can break packet ordering. For example, a respawn packet may be sent after later packets, which can cause clients to get stuck waiting indefinitely.

Changes

This PR applies two fixes:

  • After async packet processing completes, packets are sent or received directly through the injector instead of going through the public sendServerPacket / receiveClientPacket API again.

    • This avoids invoking listeners a second time.
    • In particular, it prevents duplicate MONITOR listener execution.
  • sendServerPacket / receiveClientPacket no longer delay packets solely because of MONITOR listeners.

    • MONITOR listeners are still executed on the main thread.
    • The packet continues immediately instead of being delayed by one tick.
    • This preserves packet ordering when only read-only listeners are present.
  • Also fixed some deprecations in the injector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant