diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java index bd83a2c2..f694d0fe 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventAbstractionListener.java @@ -35,6 +35,7 @@ import com.sk89q.worldguard.bukkit.util.Blocks; import com.sk89q.worldguard.bukkit.util.Events; import com.sk89q.worldguard.bukkit.util.Materials; +import com.sk89q.worldguard.bukkit.util.WGMetadata; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.World; @@ -110,11 +111,7 @@ public class EventAbstractionListener extends AbstractListener { - /** - * Abstract {@link BlockFromToEvent}s into break and place events. - * Currently disabled as it creates a lot of new events. - */ - public static final boolean ABSTRACT_FROM_TO_EVENTS = false; + private static final String ITEM_PICKUP_DEBOUNCE_KEY = "worldguard.debounce.itemPickup"; /** * Construct the listener. @@ -557,7 +554,21 @@ public void onPlayerShearEntity(PlayerShearEntityEvent event) { @EventHandler public void onPlayerPickupItem(PlayerPickupItemEvent event) { - Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getPlayer()), event.getItem())); + Item item = event.getItem(); + + // These events happen very frequently so let's reduce their frequency + EventDebounce debounce = WGMetadata.getIfPresent(item, ITEM_PICKUP_DEBOUNCE_KEY, EventDebounce.class); + if (debounce != null && debounce.isValid()) { + if (debounce.getLastCancellation()) { + event.setCancelled(true); + } + } else { + boolean cancelled = Events.fireAndTestCancel(new DestroyEntityEvent(event, create(event.getPlayer()), event.getItem())); + if (cancelled) { + event.setCancelled(true); + } + WGMetadata.put(item, ITEM_PICKUP_DEBOUNCE_KEY, new EventDebounce(cancelled)); + } } @EventHandler diff --git a/src/main/java/com/sk89q/worldguard/bukkit/listener/EventDebounce.java b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventDebounce.java new file mode 100644 index 00000000..6facf9fb --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/listener/EventDebounce.java @@ -0,0 +1,41 @@ +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) WorldGuard team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldguard.bukkit.listener; + +class EventDebounce { + + private static final int DEBOUNCE_TIME = 5000; + + private final long time = System.currentTimeMillis(); + private final boolean cancelled; + + EventDebounce(boolean cancelled) { + this.cancelled = cancelled; + } + + public boolean isValid() { + return System.currentTimeMillis() - time < DEBOUNCE_TIME; + } + + public boolean getLastCancellation() { + return cancelled; + } + +}