[SPIGOT-2478] PlayerInteractEvent fires twice during the same tick when teleporting Created: 03/Jul/16  Updated: 05/Jul/16

Status: Reopened
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Maximilian Micko Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: 1.10


 Description   

If you teleport the player while he uses an item in hand by right-clicking a block, the PlayerInteractEvent will fire twice, once as RIGHT_CLICK_BLOCK and once as RIGHT_CLICK_AIR.
However, if he right-clicks the air from the start, it will only fire once.
It will also fire once if the player is facing a block at the location he is telporting to.

Demonstration: https://github.com/McDjuady/Mc-Interact-TP-Spike
This Plugin teleports the player to spawn once he uses an Ender Eye and also reduces the ammount of the eyes by one.

  • Build the Plugin and drop it into your server
  • Get some EnderEyes
  • Make sure you don't face any blocks at your spawn location
  • Use the eye without clicking a block => 1 Eye consumed
  • Use the eye by clicking a block => 2 Eyes consumed
  • Place some blocks infront of the spawn so that you face them once teleported there
  • Use the eye by clicking a block => 1 Eye consumed

All of this is done with only the Main Hand being passed to the listener



 Comments   
Comment by Maximilian Micko [ 04/Jul/16 ]

I added ProtocolLib to the Test plugin to prove that the issue is serverside, not clientside.

Here is whatis happening:

  • The minecraft client sends packets based on these conditions:
  • If you press rightclick while holding anything in hand, a BlockPlace packet will be sent, regardless of whether the item in hand is a block or not
  • If you press rightclick while facing a block, a UseItem packet will be sent, regardless of whether you hold an item in hand or not
  • If you click a block while holding an item, both packets will be sent in the following order: UseItem(Main Hand), BlockPlace(If item in Main Hand), UseItem(Off Hand), BlockPlace(If Item in OffHand)
  • Let's assume the player is holding an item in the main hand and clicks a block. The packets will be sent in the order provided above.
  • Spigot first evaluates the Packets in order, so the UseItem event will be processed first and fires a PlayerInteractEvent at PlayerInteractManager:492
  • After this Spigot evealuates this packet, the next packet will be the BlockPlace packet. The relevant part of the Method is at PlayerConnection:926-966 Spigot does some raycasts here to check if the player is clicking a block or not, to prevent 'rogue armswings'. Normally this check would be successfull if the player clicked a block. However this fails, since we teleported the player beforhand. Because of that Spigot assumes the player clicked the air and fires a PlayerInteractEvent of the type RIGHT_CLICK_AIR.

And so we get 2 PlayerInteractEvents from the same action.
This could be fixed by checking whether the PlayerInteractManager already handled the event before checking the movingobjectposition

I hope this explanation was usefull To test this for yourself, check the repo mentioned in the OP

Cheers
Max

Comment by md_5 [ 04/Jul/16 ]

Interacts are fired purely on what the client does.

Generated at Tue Apr 08 02:45:48 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.