PaperMC / PaperMC/Paper

Stabbing a block with a spear does not trigger left click event

Open
#13,779 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: accepted version: 26.1.2
Dominant language
Java
Stars
12.7k
Forks
3.5k
Avg merge
3d 13h
Merged PRs (30d)
11

Description

Expected behavior

When I hold a spear and stab a block, a PlayerInteractEvent with Action.LEFT_CLICK_BLOCK should be fired

Observed/Actual behavior

No interaction event is fired.

Steps/models to reproduce
  1. Hold a spear
  2. Look at a block
  3. Left-click
Plugin and Datapack List
> pl
[22:50:17 INFO]: ℹ Server Plugins (1):
[22:50:17 INFO]: Paper Plugins:
[22:50:17 INFO]:  - LeftClickPlugin
> datapack list
[22:51:07 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[22:51:07 INFO]: There are no more data packs available
Paper version
> version
[22:51:25 INFO]: Checking version, please wait...
[22:51:25 INFO]: This server is running Paper version 26.1.2-5-main@d61d8df (2026-04-11T14:20:55Z) (Implementing API version 26.1.2.build.5-alpha)
You are running the latest version
Previous version: 26.1.2-DEV-8987f91 (MC: 26.1.2)
Other

Usually, the left click should be detected because the Player Action packet is fired. However, the code that triggers the event for swords (calling handleBlockBreakAction) is not present for the STAB action type, so no event is fired.

This can be seen by adding breakpoints to handlePlayerAction and PlayerInteractEvent#<init>:

For swords:

Breakpoint reached
	at net.minecraft.server.network.ServerGamePacketListenerImpl.handlePlayerAction(ServerGamePacketListenerImpl.java:1959)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:51)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:10)
	at net.minecraft.network.PacketProcessor$ListenerAndPacket.handle(PacketProcessor.java:99)
	at net.minecraft.network.PacketProcessor.executeSinglePacket(PacketProcessor.java:33)
	at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1532)
	at net.minecraft.server.MinecraftServer.recordTaskExecutionTimeWhileWaiting(MinecraftServer.java:1262)
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1378)
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:304)
	at net.minecraft.server.MinecraftServer$$Lambda/0x000000001dec78b0.run(Unknown Source:-1)
	at java.lang.Thread.runWith(Thread.java:1487)
	at java.lang.Thread.run(Thread.java:1474)
Action type is START_DESTROY_BLOCK
Breakpoint reached
	at org.bukkit.event.player.PlayerInteractEvent.<init>(PlayerInteractEvent.java:56)
	at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:643)
	at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:611)
	at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:607)
	at net.minecraft.server.level.ServerPlayerGameMode.handleBlockBreakAction(ServerPlayerGameMode.java:206)
	at net.minecraft.server.network.ServerGamePacketListenerImpl.handlePlayerAction(ServerGamePacketListenerImpl.java:2055)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:51)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:10)
	at net.minecraft.network.PacketProcessor$ListenerAndPacket.handle(PacketProcessor.java:99)
	at net.minecraft.network.PacketProcessor.executeSinglePacket(PacketProcessor.java:33)
	at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1532)
	at net.minecraft.server.MinecraftServer.recordTaskExecutionTimeWhileWaiting(MinecraftServer.java:1262)
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1378)
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:304)
	at net.minecraft.server.MinecraftServer$$Lambda/0x000000001dec78b0.run(Unknown Source:-1)
	at java.lang.Thread.runWith(Thread.java:1487)
	at java.lang.Thread.run(Thread.java:1474)

For spears:

Breakpoint reached
	at net.minecraft.server.network.ServerGamePacketListenerImpl.handlePlayerAction(ServerGamePacketListenerImpl.java:1959)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:51)
	at net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.handle(ServerboundPlayerActionPacket.java:10)
	at net.minecraft.network.PacketProcessor$ListenerAndPacket.handle(PacketProcessor.java:99)
	at net.minecraft.network.PacketProcessor.executeSinglePacket(PacketProcessor.java:33)
	at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1532)
	at net.minecraft.server.MinecraftServer.recordTaskExecutionTimeWhileWaiting(MinecraftServer.java:1262)
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1378)
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:304)
	at net.minecraft.server.MinecraftServer$$Lambda/0x000000001dec78b0.run(Unknown Source:-1)
	at java.lang.Thread.runWith(Thread.java:1487)
	at java.lang.Thread.run(Thread.java:1474)
Action type is STAB
// no PlayerInteractEvent is created because the match arm for STAB does not do that

LeftClickPlugin does nothing besides register an event listener that listens for click events:

package blue.lhf.leftclick;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.block.Action;
import org.bukkit.plugin.java.JavaPlugin;

public class LeftClickPlugin extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onInteract(PlayerInteractEvent event) {
        Action action = event.getAction();

        switch (action) {
            case LEFT_CLICK_AIR:
            case LEFT_CLICK_BLOCK:
                event.getPlayer().sendMessage("leftclick");
                break;

            case RIGHT_CLICK_AIR:
            case RIGHT_CLICK_BLOCK:
                event.getPlayer().sendMessage("rightclick");
                break;

            default: // The only remaining action is PHYSICAL, which is ignored
                break;
        }
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ServerGamePacketListenerImpl.handlePlayerAction and compare the STAB path with the START_DESTROY_BLOCK path through ServerPlayerGameMode.handleBlockBreakAction and CraftEventFactory.callPlayerInteractEvent. Verify that stabbing a block with a spear produces PlayerInteractEvent with Action.LEFT_CLICK_BLOCK, while preserving the existing sword behavior; no test file is named in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.