setCancelled(true); DropItemEvent


#1

Hello guys.
So, im making my own registration / login plugin. So, when the player joins, i need to stop any kind of action until the player make the authentication. Ive been trying use a listener to event DropItemEvent, but when the player press the Q button, the item disappear from the inventory, even if the player logout, and login, the item is not there.
part of my code:

@Listener
public void onPlayerItemDrop(DropItemEvent dropItemEvent, @First Player player) {
    this.database.checkLoginStatus(dropItemEvent, player);
}

in method checkLogin i check in a ConcurrentHashMap if player is already authenticated, (just a test for now) and if not, it cancel the event.

public void checkLoginStatus(Cancellable event, Player player) {
    if ( !this.getPlayer(player).map(Account::isUserOnline).orElse(false) ) {
        event.setCancelled(true);
    }
}

it works for every single event, to move, to openInv, interact, block break, etc… but only drop event it is not working…
Can someone help me ?
Sorry bad english.


#2

Change the event to

DropItemEvent.Pre

I believe that should fix it. If not capture the item and give the item back to the player (may need a delay of 1 tick)


#3

Already tried it… doesnt work at all…
In the second option, how i would do that ?


#4

Something like this. Please remember to set the player variable and your plugin.

    final Player player = null;
    List<ItemStackSnapshot> list = new ArrayList<>(event.getDroppedItems());
    Task.builder().delayTicks(1).execute(() -> list.forEach(i -> player.getInventory().offer(i.createStack()))).submit(YourPlugin.getPlugin().getContainer());

#5

Oh, that works!
Thanks buddie.
That was an issue, right ? cause whats the point of cancelling an event not work


#6

No. Its just based on timing of the actual event. The real event fires after the item has been taken from the inventory.
While Sponge could reset the inventory if the event is cancelled, im guessing they dont to stop confusion, keep compatibility and because of the scheduler.


#7

Oh, that`s make sense…
But what’s the difference between ItemStack and ItemStackSnapshot ?


#8

Itemstack is a live itemstack meaning it is somewhere in the world and changing values on the itemstack will edit the item itself.

A snapshot means its a copy of a itemstack and modifying it does not change anything in the world.

The reason why DropItemEvent.Pre is a itemstacksnapshot is despite it is refering to a live item stack, that itemstack has been removed from the world and being converted into a Item Entity