Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-7192

PlayerInteractEvent is not fired when left-clicking a hidden player


    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Minor Minor
    • None
    • None
    • openjdk version "17.0.5" 2022-10-18 LTS / macOS 13

    • 3609-Spigot-6198b5a-f3dab3a (MC: 1.19.2)
    • Yes

      If a player left-clicks the air while a hidden player is standing in front of them, I expect PlayerInteractEvent to be fired with Action.LEFT_CLICK_AIR. Instead, no PlayerInteractEvent event handlers are invoked.

      I assume that while the Minecraft client thinks that the player is hitting air, Spigot thinks that the player is hitting the hidden player, and is not firing the event.

      Here's a minimal plugin source that can be used to reproduce this issue:

      public class Main extends JavaPlugin implements Listener {
      	public void onEnable() {
      		Bukkit.getPluginManager().registerEvents(this, this);
      	private void onPlayerJoin(PlayerJoinEvent event) {
      		//Hide all players from each other
      		for(Player player : Bukkit.getOnlinePlayers()) {
      			for(Player otherPlayer : Bukkit.getOnlinePlayers()) {
      				player.hidePlayer(this, otherPlayer);
      	private void onPlayerInteract(PlayerInteractEvent event) {
      		//Send a message when a player left-clicks the air
      		if(event.getAction() == Action.LEFT_CLICK_AIR) {
      			Bukkit.broadcastMessage(event.getPlayer().getName() + " left-clicked the air!");

      To reproduce, log in with 2 accounts to a server running this plugin. Have one player stand somewhere identifiable, like on a tower of blocks. Have the other player punch the air where the other player should be standing, and notice how the broadcast message is not displayed in the chat.

      I'm unfamiliar with CraftBukkit's source code so I'm not sure if there's more to it, but FWIW I was able to resolve this locally by changing line 1196 of PlayerConnection.patch to this:

      +        org.bukkit.util.RayTraceResult result = this.player.level.getWorld().rayTrace(origin, origin.getDirection(), d3, org.bukkit.FluidCollisionMode.NEVER, false, 0.1, entity -> entity != this.player.getBukkitEntity() && (!(entity instanceof Player entityPlayer) || this.player.getBukkitEntity().canSee(entityPlayer)));


            Doc Doc
            Tagavari Tagavari
            1 Vote for this issue
            3 Start watching this issue