Player interact cannot deny block use but allow place
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 3.5k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 11
Description
Expected behavior
When in PlayerInteractEvent the following are set:
event.setUseItemInHand(Event.Result.ALLOW);
event.setUseInteractedBlock(Event.Result.DENY);
You'd expect that using the block (eg: opening a chest, or flipping a trapdoor) is denied, but placing a block is still possible.
Observed/Actual behavior
No block placing is allowed anymore.
Steps/models to reproduce
Have a plugin with the following:
@EventHandler
public void onPlayerInteract(PlayerInteractEvent pie) {
if (pie.getAction() != Action.RIGHT_CLICK_BLOCK) return;
pie.setCancelled(false);
pie.setUseItemInHand(Event.Result.ALLOW);
pie.setUseInteractedBlock(Event.Result.DENY);
}
Attempt to place any block.
Plugin and Datapack List
Not relevant, see above.
Paper version
1.21.11-127-main@bd74bf6 (2026-03-10T02:55:23Z)
Other
This used to work just fine in the past (eg: 1.8), and investigating the root cause of the issue seems to lead to this commit (1.20.5) as the original root cause of the issue:
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/735b2d0d7f10bc3b3a816e103cc86af8cb1ec645#nms-patches%2Fnet%2Fminecraft%2Fserver%2Flevel%2FPlayerInteractManager.patch?t=316
Notice that prior to this diff, the code would enuminteractionresult = ... (and set the interaction result to PASS) but let the execution continue and the code below, as long as the previous interaction wasn't SUCCESS, would do the block placing. Since it now directly returns the PASS result, it will never attempt to place the block.
As of latest, the issue still resides in https://github.com/PaperMC/Paper/blob/main/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch#L384 .
A simple/minimal diff that fixes this issue is the following (note, it still has unneeded inventory resync logic so the item looks to do a jump in the inventory client-side, but the expected serverside behavior is correct):
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
index 84d19d79e77cec6a5d64f59fbcce703e467b2407..87bb20f74716342e504c0cecfab616dc367818b3 100755
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -526,7 +526,7 @@ public class ServerPlayerGameMode {
}
// Paper end - Fix inventory desync
this.player.resyncUsingItem(this.player); // Paper - Properly cancel usable items
- return (event.useItemInHand() != org.bukkit.event.Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
+ if (event.useItemInHand() != org.bukkit.event.Event.Result.ALLOW) return InteractionResult.SUCCESS; // Paper - handle useInteractedBlock and useItemInHand separately
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
MenuProvider menuProvider = blockState.getMenuProvider(level, blockPos);
if (menuProvider != null && player.openMenu(menuProvider).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
@@ -553,9 +553,10 @@ public class ServerPlayerGameMode {
}
}
}
-
+ } { // Paper - handle useInteractedBlock and useItemInHand separately
if (!stack.isEmpty() && !this.interactResult) { // add !interactResult SPIGOT-764
UseOnContext useOnContext = new UseOnContext(player, hand, hitResult);
+ ItemStack itemStack = stack.copy(); // Paper - handle useInteractedBlock and useItemInHand separately
InteractionResult interactionResult1;
if (player.hasInfiniteMaterials()) {
int count = stack.getCount();
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch around line 384 and trace the PlayerInteractEvent handling for useInteractedBlock and useItemInHand. Reproduce the provided plugin scenario, then verify that denying block use still permits block placement while block interactions remain denied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100