PaperMC / Paper

The most widely used, high performance Minecraft server that aims to fix gameplay and mechanics inconsistencies
https://papermc.io/
Other
10.04k stars 2.34k forks source link

PlayerInteractEvent calls LEFT_CLICK_AIR after RIGHT_CLICK_BLOCK in Adventure game mode. #6315

Open LoonyRules opened 3 years ago

LoonyRules commented 3 years ago

Expected behavior

Only one event call for the PlayerInteractEvent when a player in Adventure interacts with an item that is in their hand on a block. For example: trying to spawn a Pig from a PIG_SPAWN_EGG item.

Observed/Actual behavior

The PlayerInteractEvent was triggered twice claiming a LEFT_CLICK_AIR action after a RIGHT_CLICK_BLOCK.

[11:02:38 INFO]: [paper-test] PlayerInteractEvent: LoonyRules - HAND - RIGHT_CLICK_BLOCK - ALLOW - DEFAULT
[11:02:38 INFO]: [paper-test] PlayerInteractEvent: LoonyRules - HAND - LEFT_CLICK_AIR - DENY - DEFAULT

Steps/models to reproduce

  1. Download latest Paper 1.16.5.
  2. Create a plugin with code in that debugs the PlayerInteractEvent. In our example we printed into console every time the event got triggered and subtracted the quantity of the item used in the interaction. This is our own code on the whole server to show the bug.

    @EventHandler
    public void onPlayerInteractEvent(@NotNull final PlayerInteractEvent event) {
    this.getLogger().info(
    String.format(
      "PlayerInteractEvent: %s - %s - %s - %s - %s",
      event.getPlayer().getName(), event.getHand(), event.getAction(), event.useInteractedBlock(),
      event.useItemInHand()
    )
    );
    
    // Visually show the bug by decreasing itemstack amount every interact.
    final ItemStack itemStack = event.getItem();
    if (itemStack != null) {
    itemStack.subtract();
    }
    }
  3. Upload the plugin to the server's plugins folder and start the server.
  4. Join the server and set your gamemode to Adventure.
  5. Give yourself an item that adventure mode users can interact with. A good example here is a PIG_SPAWN_EGG. Make sure you have 2 of these at least.
  6. Right-click a block to spawn the Pig. Ensure you click once.
  7. You should no longer have the item even though you spawned 1 pig. Look at the debug in console, you should see what was outlined in the "Observed/Actual behavior" section.

Plugin list

Custom plugin that only has the PlayerInteractEvent code shared in reproduction steps.

Paper version

Checking version, please wait... This server is running Paper version git-Paper-783 (MC: 1.16.5) (Implementing API version 1.16.5-R0.1-SNAPSHOT) You are running the latest version

Agreements

Other

No response

MiniDigger commented 3 years ago

Related to #5017 #5015

electronicboy commented 3 years ago

idk if I'm missing something, but, 1.16 is generally frozen and this looks like the general "double PIE event fires" which has been the case for CB since the offhand was added?

Like, it was filtered down more in the past for adventure at the cost of plugins no longer being able to access information, I'm not really sure if this is a bug as much as an unfortunate limitation of how this stuff works as a whole. I have been kinda speaking to mojang about this issue in general, but, no idea if anything will come of it

LoonyRules commented 3 years ago
  1. Apologies if you've frozen 1.16.5 and I created this issue anyway. Had no idea.
  2. Also had no idea this bug has been a thing since OFF_HAND introduction, never noticed it before until around March time for a project we were doing.
  3. Sad thing is this is still going to be an issue going forward and I can't think of any vanilla mechanic where a LEFT_CLICK_AIR after an item was interacted with on a block would need to be used. It feels like the LEFT_CLICK_AIR just should not be happening and shy's people away from Adventure gamemode. Would love if it was looked into and patched for later versions at the very least but up to you guys what you do of course.
ChickenSaysBak commented 1 year ago

Still occurs in 1.19.3 This server is running Paper version git-Paper-386 (MC: 1.19.3) (Implementing API version 1.19.3-R0.1-SNAPSHOT) (Git: 4da844f)

I reproduced using this code:

public class InteractTest extends JavaPlugin implements Listener {

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

    @EventHandler
    public void onInteract(PlayerInteractEvent event) {
        event.setCancelled(true);
        Bukkit.broadcastMessage(event.getHand() + " " + event.getAction());
    }

}

It also occurs using event.setUseInteractedBlock(Result.DENY); All gamemodes besides ADVENTURE work as expected.