diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java index 81f44f83af..eac33a6113 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntityEventListener.java @@ -43,6 +43,7 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.world.block.BlockType; import io.papermc.lib.PaperLib; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.World; @@ -195,9 +196,12 @@ public void creatureSpawnEvent(CreatureSpawnEvent event) { } return; } - if (BukkitEntityUtil.checkEntity(entity, plot)) { - event.setCancelled(true); - } + + BukkitEntityUtil.checkEntityAsync(entity, plot.getBasePlot(false)).thenAcceptAsync(toRemove -> { + if(toRemove) { + entity.remove(); + } + }, Bukkit.getScheduler().getMainThreadExecutor(BukkitPlatform.getPlugin(BukkitPlatform.class))); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @@ -421,13 +425,17 @@ public void onVehicleCreate(VehicleCreateEvent event) { return; } Plot plot = area.getOwnedPlotAbs(location); - if (plot == null || BukkitEntityUtil.checkEntity(entity, plot)) { - entity.remove(); + if (plot == null) { return; } - if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { - entity.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot)); - } + + BukkitEntityUtil.checkEntityAsync(entity, plot.getBasePlot(false)).thenAcceptAsync(toRemove -> { + if (toRemove) { + entity.remove(); + } else if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { + entity.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot)); + } + }, Bukkit.getScheduler().getMainThreadExecutor(BukkitPlatform.getPlugin(BukkitPlatform.class))); } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntitySpawnListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntitySpawnListener.java index f1f05b6532..7a250f253c 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntitySpawnListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/EntitySpawnListener.java @@ -18,6 +18,7 @@ */ package com.plotsquared.bukkit.listener; +import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.util.BukkitEntityUtil; import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.core.PlotSquared; @@ -27,6 +28,7 @@ import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.flag.implementations.DoneFlag; import io.papermc.lib.PaperLib; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Block; @@ -155,9 +157,11 @@ public void creatureSpawnEvent(EntitySpawnEvent event) { event.setCancelled(true); } if (type == EntityType.ENDER_CRYSTAL) { - if (BukkitEntityUtil.checkEntity(entity, plot)) { - event.setCancelled(true); - } + BukkitEntityUtil.checkEntityAsync(entity, plot).thenAcceptAsync(toRemove -> { + if (toRemove) { + entity.remove(); + } + }, Bukkit.getScheduler().getMainThreadExecutor(BukkitPlatform.getPlugin(BukkitPlatform.class))); return; } if (type == EntityType.SHULKER) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java index 9fba3dff9d..e9d2fb8552 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java @@ -21,6 +21,7 @@ import com.destroystokyo.paper.MaterialTags; import com.google.common.base.Charsets; import com.google.inject.Inject; +import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.util.BukkitEntityUtil; import com.plotsquared.bukkit.util.BukkitUtil; @@ -1502,10 +1503,13 @@ public void onHangingPlace(HangingPlaceEvent event) { return; } } - if (BukkitEntityUtil.checkEntity(event.getEntity(), plot)) { - event.setCancelled(true); - } + Entity entity = event.getEntity(); + BukkitEntityUtil.checkEntityAsync(entity, plot.getBasePlot(false)).thenAcceptAsync(toRemove -> { + if (toRemove) { + entity.remove(); + } + }, Bukkit.getScheduler().getMainThreadExecutor(BukkitPlatform.getPlugin(BukkitPlatform.class))); } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java index becc3ddc1a..baa3c42851 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEntityUtil.java @@ -56,6 +56,7 @@ import org.bukkit.projectiles.ProjectileSource; import java.util.Objects; +import java.util.concurrent.CompletableFuture; public class BukkitEntityUtil { @@ -399,4 +400,8 @@ public static boolean checkEntity(Entity entity, Plot plot) { return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED); } + public static CompletableFuture checkEntityAsync(Entity entity, Plot plot) { + return CompletableFuture.supplyAsync(() -> checkEntity(entity, plot)); + } + } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 7d1065e4fe..445150bedf 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -45,12 +45,14 @@ import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL; import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY; @@ -102,7 +104,7 @@ public int[] countEntities(@NonNull Plot plot) { Chunk chunk = world.getChunkAt(x, z); final Entity[] entities = chunk.getEntities(); for (Entity entity : entities) { - if (entity instanceof Player) { + if (entity instanceof Player || entity instanceof Item) { continue; } @@ -119,6 +121,11 @@ public int[] countEntities(@NonNull Plot plot) { return count; } + @Override + public CompletableFuture countEntitiesAsync(final Plot plot) { + return CompletableFuture.supplyAsync(() -> countEntities(plot)); + } + @Override public boolean regenerateRegion( final @NonNull Location pos1, diff --git a/Core/src/main/java/com/plotsquared/core/command/Caps.java b/Core/src/main/java/com/plotsquared/core/command/Caps.java index dd3cf7ec84..6a331ab703 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Caps.java +++ b/Core/src/main/java/com/plotsquared/core/command/Caps.java @@ -64,14 +64,15 @@ public boolean onCommand(final PlotPlayer player, final String[] args) { player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large")); return false; } - player.sendMessage(TranslatableCaption.of("info.plot_caps_header")); - final int[] countedEntities = plot.countEntities(); - sendFormatted(plot, player, MobCapFlag.class, countedEntities, "mobs", CAP_MOB); - sendFormatted(plot, player, HostileCapFlag.class, countedEntities, "hostile", CAP_MONSTER); - sendFormatted(plot, player, AnimalCapFlag.class, countedEntities, "animals", CAP_ANIMAL); - sendFormatted(plot, player, VehicleCapFlag.class, countedEntities, "vehicle", CAP_VEHICLE); - sendFormatted(plot, player, MiscCapFlag.class, countedEntities, "misc", CAP_MISC); - sendFormatted(plot, player, EntityCapFlag.class, countedEntities, "entities", CAP_ENTITY); + plot.countEntitiesAsync().thenAccept(countedEntities -> { + player.sendMessage(TranslatableCaption.of("info.plot_caps_header")); + sendFormatted(plot, player, MobCapFlag.class, countedEntities, "mobs", CAP_MOB); + sendFormatted(plot, player, HostileCapFlag.class, countedEntities, "hostile", CAP_MONSTER); + sendFormatted(plot, player, AnimalCapFlag.class, countedEntities, "animals", CAP_ANIMAL); + sendFormatted(plot, player, VehicleCapFlag.class, countedEntities, "vehicle", CAP_VEHICLE); + sendFormatted(plot, player, MiscCapFlag.class, countedEntities, "misc", CAP_MISC); + sendFormatted(plot, player, EntityCapFlag.class, countedEntities, "entities", CAP_ENTITY); + }); return true; } diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 08be7d1fc5..807b78d133 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -1215,6 +1215,10 @@ public int[] countEntities() { return this.regionManager.countEntities(this); } + public CompletableFuture countEntitiesAsync() { + return this.regionManager.countEntitiesAsync(this); + } + /** * Returns true if a previous task was running * diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java index 765bdc7453..4f9d47c733 100644 --- a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java @@ -48,6 +48,7 @@ import java.io.File; import java.util.Collection; import java.util.Set; +import java.util.concurrent.CompletableFuture; public abstract class RegionManager { @@ -88,6 +89,8 @@ public static BlockVector2 getRegion(Location location) { */ public abstract int[] countEntities(Plot plot); + public abstract CompletableFuture countEntitiesAsync(Plot plot); + public void deleteRegionFiles(final String world, final Collection chunks, final Runnable whenDone) { TaskManager.runTaskAsync(() -> { for (BlockVector2 loc : chunks) {