Implement suspend command requirements and optimize packet handling#358
Conversation
…ocking - add CommandSendPacketBlockerListener for blocking commands to specific players - create SuspendRequirementService for managing command execution requirements - integrate new listener into existing event handling for command execution - update NmsProvider to support new command blocking functionality
…uirement service - ensure triggerRefreshForSender is called consistently for both adding and removing UUIDs
…pend requirement service - streamline logic for adding and removing blocked command packets - trigger refresh for sender only when a new packet is added
…ket handling - implement SuspendRequirementTestCommand for testing suspend command requirements - modify CommandSendPacketBlockerListener to manage received command packets - update SuspendRequirementServiceImpl to provide command send packet blocker listener
- implement withSuspendPlayerRequirement function to refresh command visibility - cache requirement results for improved performance during command execution
|
This PR contains changes that modified the public API. To update the reference ABI dumps: ./gradlew updateKotlinAbi
git add **/api/**
git commit -m "Update ABI reference"
git pushAfter updating, the CI will pass. Make sure the changes are backward compatible. |
…on logic - add invalidate method to clear cached requirements for players - invoke invalidate on player removal from blocked command packets
|
This PR contains changes that modified the public API. To update the reference ABI dumps: ./gradlew updateKotlinAbi
git add **/api/**
git commit -m "Update ABI reference"
git pushAfter updating, the CI will pass. Make sure the changes are backward compatible. |
…istency - update variable name in CommandSendPacketBlockerListener and its implementations - ensure consistent naming across related classes and methods
…mmandPacket - update variable name for clarity in CommandSendPacketBlockerListener - adjust method names accordingly in SuspendRequirementServiceImpl - ensure consistency in command packet handling across implementations
…escription - update parameter description for allowIfNonPlayer to specify it bypasses player-only requirement
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef306f6fea
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Adds infrastructure for suspendable (coroutine-based) CommandAPI requirements on Paper, with per-player cached results refreshed asynchronously when the command tree is sent. To hide intermediate state from the client, a version-specific clientbound packet listener replaces the first ClientboundCommandsPacket for blocked players with a placeholder "commands-are-loading" tree and cancels subsequent packets until the async refresh completes.
Changes:
- New public API
withSuspendPlayerRequirementplus internalSuspendRequirementServiceand itsSuspendRequirementServiceImpl(Caffeine caches,AsyncPlayerSendCommandsEvent/PlayerConnectionCloseEventlisteners). - New
CommandSendPacketBlockerListenerabstract base in NMS common and per-version implementations (v1_21_11,v26_1), wired throughNmsProvider.createCommandSendPacketBlockerListener. - Listener/packet listener registration in
ListenerManagerandPacketApiLoader, plus a test subcommand and a version bump to3.16.0.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| surf-api-paper/.../command/requirement/SuspendCommandRequirements.kt | New public extension withSuspendPlayerRequirement with KDoc. |
| surf-api-paper/.../command/requirement/SuspendRequirementService.kt | New @InternalSurfApi service interface and companion accessor. |
| surf-api-paper/.../command/SuspendRequirementServiceImpl.kt | Service implementation: requirement caches, refresh coroutines, event listener. |
| surf-api-paper/.../listener/ListenerManager.kt | Registers the new event listener on enable. |
| surf-api-paper/.../packet/PacketApiLoader.kt | Registers the new command-send blocker packet listener on enable. |
| surf-api-paper-nms-common/.../NmsProvider.kt | Adds createCommandSendPacketBlockerListener to provider interface. |
| surf-api-paper-nms-common/.../CommandSendPacketBlockerListener.kt | New abstract base tracking first-packet state per player. |
| surf-api-paper-nms-v1-21-11/.../V1_21_11NmsProvider.kt | Wires v1.21.11 blocker implementation. |
| surf-api-paper-nms-v1-21-11/.../V1_21_11CommandSendPacketBlockerListenerImpl.kt | v1.21.11 clientbound packet replacement/cancellation. |
| surf-api-paper-nms-v26-1/.../V26_1NmsProvider.kt | Wires v26.1 blocker implementation. |
| surf-api-paper-nms-v26-1/.../V26_1CommandSendPacketBlockerListenerImpl.kt | v26.1 clientbound packet replacement/cancellation. |
| surf-api-paper/api/surf-api-paper.api | Generated ABI updates for new public symbols. |
| surf-api-paper-plugin-test/.../SuspendRequirementTestCommand.kt | Demo subcommand exercising the new requirement API. |
| surf-api-paper-plugin-test/.../SurfApiTestCommand.java | Registers the new test subcommand. |
| gradle.properties | Bumps project version to 3.16.0. |
- remove registration of command send packet blocker listener in PacketApiLoader
- check player connection status before caching requirement - store requirement result in cache only if player is connected
This pull request introduces a new system for suspending and conditionally blocking command packet sending to players, enabling asynchronous or conditional command requirements in the plugin. It adds an infrastructure for "suspendable" command requirements, implements packet blocking for command updates on two Minecraft versions, and provides test commands to demonstrate the new functionality. Additionally, it ensures the new listeners are registered in the plugin lifecycle.
Core infrastructure for suspendable command requirements:
SuspendRequirementServiceImplas the implementation forSuspendRequirementService, providing coroutine-based, per-player, cacheable command requirements and managing the lifecycle of blocked command packets. It includes an event listener for command updates and connection closures, and registers a version-specific packet blocker listener.CommandSendPacketBlockerListenerabstract class, which tracks which players should have command packets blocked and exposes a method to remove them from the tracking set.NmsProviderinterface to include a method for creating aCommandSendPacketBlockerListenerfor a set of blocked players.Version-specific packet blocker implementations:
V1_21_11CommandSendPacketBlockerListenerImplandV26_1CommandSendPacketBlockerListenerImpl, which intercept outgoing command packets and, for blocked players, send a placeholder "commands-are-loading" command tree instead. [1] [2]NmsProviderversions. [1] [2]Integration and registration:
Testing and demonstration:
SuspendRequirementTestCommandwith subcommands to demonstrate and test the suspendable requirement system, including showing/hiding commands and a conditional command that is only available after a delay and if a condition is met.Miscellaneous:
3.16.0ingradle.properties.These changes collectively enable advanced, asynchronous command gating and improve the flexibility of command requirements in the plugin.