Remove metadata when the entity is done.

Apparently Bukkit doesn't actually do this.
Fixes WORLDGUARD-4169.
This commit is contained in:
wizjany 2020-02-13 23:18:28 -05:00
parent 0d860bfca7
commit d95c6af1be
3 changed files with 34 additions and 9 deletions

View File

@ -236,6 +236,15 @@ public static void trackParentCause(Metadatable target, Object parent) {
WGMetadata.put(target, CAUSE_KEY, parent);
}
/**
* Remove a parent cause from a {@code Metadatable} object.
*
* @param target the target
*/
public static void untrackParentCause(Metadatable target) {
WGMetadata.remove(target, CAUSE_KEY);
}
/**
* Builds causes.
*/

View File

@ -75,4 +75,13 @@ public static <T> T getIfPresent(Metadatable target, String key, Class<T> expect
return null;
}
/**
* Removes metadata from the target.
*
* @param target the target
* @param key the key
*/
public static void remove(Metadatable target, String key) {
target.removeMetadata(key, WorldGuardPlugin.inst());
}
}

View File

@ -35,6 +35,7 @@
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
import com.sk89q.worldguard.bukkit.internal.WGMetadata;
import com.sk89q.worldguard.bukkit.listener.debounce.BlockPistonExtendKey;
import com.sk89q.worldguard.bukkit.listener.debounce.BlockPistonRetractKey;
import com.sk89q.worldguard.bukkit.listener.debounce.EventDebounce;
@ -302,16 +303,19 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) {
Events.fireToCancel(event, new PlaceBlockEvent(event, cause, block.getLocation(), toType));
if (event.isCancelled() && !wasCancelled && entity instanceof FallingBlock) {
FallingBlock fallingBlock = (FallingBlock) entity;
final Material material = fallingBlock.getBlockData().getMaterial();
if (!material.isItem()) return;
ItemStack itemStack = new ItemStack(material, 1);
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
item.setVelocity(new Vector());
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
item.remove();
if (entity instanceof FallingBlock) {
if (event.isCancelled() && !wasCancelled) {
FallingBlock fallingBlock = (FallingBlock) entity;
final Material material = fallingBlock.getBlockData().getMaterial();
if (!material.isItem()) return;
ItemStack itemStack = new ItemStack(material, 1);
Item item = block.getWorld().dropItem(fallingBlock.getLocation(), itemStack);
item.setVelocity(new Vector());
if (Events.fireAndTestCancel(new SpawnEntityEvent(event, create(block, entity), item))) {
item.remove();
}
}
Cause.untrackParentCause(entity);
}
}
}
@ -321,6 +325,9 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) {
public void onEntityExplode(EntityExplodeEvent event) {
Entity entity = event.getEntity();
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR));
if (entity instanceof Creeper) {
Cause.untrackParentCause(entity);
}
}
@EventHandler(ignoreCancelled = true)