From 658f2a3fc319ee6d168fcd355bb365e3f134e3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 12 Apr 2020 01:23:13 +0200 Subject: [PATCH 1/4] Finalize entity type categorisation --- .../plotsquared/bukkit/util/BukkitUtil.java | 23 ++++++++++++++++++- .../plotsquared/plot/commands/Debug.java | 3 +++ .../plot/util/entity/EntityCategories.java | 17 +++++++------- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java index eddd3473c..38205b5e9 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java @@ -60,14 +60,23 @@ import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.WallSign; import org.bukkit.entity.Ambient; import org.bukkit.entity.Animals; +import org.bukkit.entity.AreaEffectCloud; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Boss; import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.EnderSignal; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.EvokerFangs; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Explosive; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Firework; import org.bukkit.entity.Ghast; import org.bukkit.entity.Golem; import org.bukkit.entity.Hanging; +import org.bukkit.entity.Item; +import org.bukkit.entity.LightningStrike; import org.bukkit.entity.Monster; import org.bukkit.entity.NPC; import org.bukkit.entity.Phantom; @@ -594,8 +603,20 @@ public class BukkitUtil extends WorldUtil { case "projectile": { allowedInterfaces.add(Projectile.class); } break; - case "decoration": { + case "other": { allowedInterfaces.add(ArmorStand.class); + allowedInterfaces.add(FallingBlock.class); + allowedInterfaces.add(Item.class); + allowedInterfaces.add(Explosive.class); + allowedInterfaces.add(AreaEffectCloud.class); + allowedInterfaces.add(EvokerFangs.class); + allowedInterfaces.add(LightningStrike.class); + allowedInterfaces.add(ExperienceOrb.class); + allowedInterfaces.add(EnderSignal.class); + allowedInterfaces.add(Firework.class); + } break; + case "player": { + allowedInterfaces.add(Player.class); } break; default: { PlotSquared.log(Captions.PREFIX + "Unknown entity category requested: " + category); diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Debug.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Debug.java index 92b701dd9..150c34a0b 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Debug.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Debug.java @@ -82,6 +82,9 @@ public class Debug extends SubCommand { .stream() .filter(category -> category.contains(entityType)) .count(); + if (categoryCount > 0) { + return; + } player.sendMessage(Captions.PREFIX.getTranslated() + entityType.getName() + " is in " + categoryCount + " categories"); }); return true; diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java index 78a518715..f40854cea 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java @@ -30,14 +30,15 @@ package com.github.intellectualsites.plotsquared.plot.util.entity; */ public class EntityCategories { - public static final EntityCategory ANIMAL = register("animal"); - public static final EntityCategory TAMEABLE = register("tameable"); - public static final EntityCategory VEHICLE = register("vehicle"); - public static final EntityCategory HOSTILE = register("hostile"); - public static final EntityCategory HANGING = register("hanging"); - public static final EntityCategory VILLAGER = register("villager"); - public static final EntityCategory PROJECTILE = register("projectile"); - public static final EntityCategory DECORATION = register("decoration"); + public static final EntityCategory ANIMAL = register("animal"); + public static final EntityCategory TAMEABLE = register("tameable"); + public static final EntityCategory VEHICLE = register("vehicle"); + public static final EntityCategory HOSTILE = register("hostile"); + public static final EntityCategory HANGING = register("hanging"); + public static final EntityCategory VILLAGER = register("villager"); + public static final EntityCategory PROJECTILE = register("projectile"); + public static final EntityCategory OTHER = register("other"); + public static final EntityCategory PLAYER = register("player"); public static EntityCategory register(final String id) { final EntityCategory entityCategory = new EntityCategory(id); From 6324bb1134fd7c2cbdfa7859cf0f64a9c5971488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 12 Apr 2020 01:47:56 +0200 Subject: [PATCH 2/4] Use entity categories in events --- .../bukkit/listeners/PlayerEvents.java | 306 +++++------------- 1 file changed, 74 insertions(+), 232 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java index 0f78aaef4..b49e9bf5e 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/listeners/PlayerEvents.java @@ -102,6 +102,7 @@ import com.github.intellectualsites.plotsquared.plot.util.Permissions; import com.github.intellectualsites.plotsquared.plot.util.RegExUtil; import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; +import com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.world.block.BlockType; import io.papermc.lib.PaperLib; @@ -116,30 +117,22 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Ageable; -import org.bukkit.entity.Animals; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Arrow; -import org.bukkit.entity.Boss; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Fireball; -import org.bukkit.entity.Golem; -import org.bukkit.entity.Hanging; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; -import org.bukkit.entity.Slime; import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Tameable; import org.bukkit.entity.ThrownPotion; import org.bukkit.entity.Vehicle; -import org.bukkit.entity.Villager; -import org.bukkit.entity.WaterMob; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -276,147 +269,40 @@ public class PlayerEvents extends PlotListener implements Listener { .getFlagContainer().getFlagMap().isEmpty()) { return false; } - switch (entity.getType()) { - case PLAYER: - return false; - case ARROW: - case DRAGON_FIREBALL: - case DROPPED_ITEM: - case EGG: - case ENDER_PEARL: - case FIREBALL: - case LLAMA_SPIT: - case SHULKER_BULLET: - case SMALL_FIREBALL: - case SNOWBALL: - case SPECTRAL_ARROW: - case SPLASH_POTION: - case THROWN_EXP_BOTTLE: - // projectile - case FALLING_BLOCK: - case PRIMED_TNT: - // Block entities - case AREA_EFFECT_CLOUD: - case ENDER_CRYSTAL: - case ENDER_SIGNAL: - case EVOKER_FANGS: - case EXPERIENCE_ORB: - case FIREWORK: - case FISHING_HOOK: - case LEASH_HITCH: - case LIGHTNING: - case UNKNOWN: - case WITHER_SKULL: - // non moving / unmovable - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED); - case ARMOR_STAND: - case ITEM_FRAME: - case PAINTING: - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MiscCapFlag.MISC_CAP_UNLIMITED); - // misc - case BOAT: - case MINECART: - case MINECART_CHEST: - case MINECART_COMMAND: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - VehicleCapFlag.VEHICLE_CAP_UNLIMITED); - case BAT: - case CHICKEN: - case CAT: - case COD: - case COW: - case DOLPHIN: - case DONKEY: - case FOX: - case HORSE: - case IRON_GOLEM: - case LLAMA: - case MULE: - case MUSHROOM_COW: - case OCELOT: - case PANDA: - case PARROT: - case PIG: - case POLAR_BEAR: - case PUFFERFISH: - case RABBIT: - case SALMON: - case SHEEP: - case SKELETON_HORSE: - case SNOWMAN: - case SQUID: - case TRADER_LLAMA: - case TROPICAL_FISH: - case TURTLE: - case VILLAGER: - case WOLF: - case ZOMBIE_HORSE: - // animal - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MobCapFlag.MOB_CAP_UNLIMITED, AnimalCapFlag.ANIMAL_CAP_UNLIMITED); - case BLAZE: - case CAVE_SPIDER: - case CREEPER: - case DROWNED: - case ELDER_GUARDIAN: - case ENDERMAN: - case ENDERMITE: - case ENDER_DRAGON: - case EVOKER: - case GHAST: - case GIANT: - case GUARDIAN: - case HUSK: - case ILLUSIONER: - case MAGMA_CUBE: - case PIG_ZOMBIE: - case SHULKER: - case SILVERFISH: - case SKELETON: - case SLIME: - case SPIDER: - case STRAY: - case VEX: - case VINDICATOR: - case WITCH: - case WITHER: - case WITHER_SKELETON: - case ZOMBIE: - case ZOMBIE_VILLAGER: - case PILLAGER: - case PHANTOM: - case RAVAGER: - // monster - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MobCapFlag.MOB_CAP_UNLIMITED, HostileCapFlag.HOSTILE_CAP_UNLIMITED); - default: - if (entity instanceof LivingEntity) { - if (entity instanceof Animals || entity instanceof WaterMob) { - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MobCapFlag.MOB_CAP_UNLIMITED, AnimalCapFlag.ANIMAL_CAP_UNLIMITED); - } else if (entity instanceof Monster) { - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MobCapFlag.MOB_CAP_UNLIMITED, HostileCapFlag.HOSTILE_CAP_UNLIMITED); - } else { - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MobCapFlag.MOB_CAP_UNLIMITED); - } - } - if (entity instanceof Vehicle) { - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - VehicleCapFlag.VEHICLE_CAP_UNLIMITED); - } - if (entity instanceof Hanging) { - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, - MiscCapFlag.MISC_CAP_UNLIMITED); - } - return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED); + + final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(entity.getType()); + + if (EntityCategories.PLAYER.contains(entityType)) { + return false; } + + if (EntityCategories.PROJECTILE.contains(entityType) || + EntityCategories.OTHER.contains(entityType) || + EntityCategories.HANGING.contains(entityType)) { + return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, + MiscCapFlag.MISC_CAP_UNLIMITED); + } + + // Has to go go before vehicle as horses are both + // animals and vehicles + if (EntityCategories.ANIMAL.contains(entityType) || + EntityCategories.VILLAGER.contains(entityType) || + EntityCategories.TAMEABLE.contains(entityType)) { + return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, + MobCapFlag.MOB_CAP_UNLIMITED, AnimalCapFlag.ANIMAL_CAP_UNLIMITED); + } + + if (EntityCategories.HOSTILE.contains(entityType)) { + return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, + MobCapFlag.MOB_CAP_UNLIMITED, HostileCapFlag.HOSTILE_CAP_UNLIMITED); + } + + if (EntityCategories.VEHICLE.contains(entityType)) { + return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED, + VehicleCapFlag.VEHICLE_CAP_UNLIMITED); + } + + return EntityUtil.checkEntity(plot, EntityCapFlag.ENTITY_CAP_UNLIMITED); } @EventHandler public void onVehicleEntityCollision(VehicleEntityCollisionEvent e) { @@ -446,53 +332,6 @@ public class PlayerEvents extends PlotListener implements Listener { @EventHandler public void onRedstoneEvent(BlockRedstoneEvent event) { Block block = event.getBlock(); -/* switch (block.getType()) { - case OBSERVER: - case REDSTONE: - case REDSTONE_ORE: - case REDSTONE_BLOCK: - case REDSTONE_TORCH: - case REDSTONE_WALL_TORCH: - case REDSTONE_WIRE: - case REDSTONE_LAMP: - case PISTON_HEAD: - case PISTON: - case STICKY_PISTON: - case MOVING_PISTON: - case LEVER: - case ACACIA_BUTTON: - case BIRCH_BUTTON: - case DARK_OAK_BUTTON: - case JUNGLE_BUTTON: - case OAK_BUTTON: - case SPRUCE_BUTTON: - case STONE_BUTTON: - case STONE_PRESSURE_PLATE: - case ACACIA_PRESSURE_PLATE: - case BIRCH_PRESSURE_PLATE: - case DARK_OAK_PRESSURE_PLATE: - case HEAVY_WEIGHTED_PRESSURE_PLATE: - case JUNGLE_PRESSURE_PLATE: - case LIGHT_WEIGHTED_PRESSURE_PLATE: - case OAK_PRESSURE_PLATE: - case SPRUCE_PRESSURE_PLATE: - case SPRUCE_DOOR: - case BIRCH_DOOR: - case JUNGLE_DOOR: - case ACACIA_DOOR: - case DARK_OAK_DOOR: - case IRON_DOOR: - case OAK_DOOR: - case IRON_TRAPDOOR: - case SPRUCE_FENCE_GATE: - case BIRCH_FENCE_GATE: - case JUNGLE_FENCE_GATE: - case ACACIA_FENCE_GATE: - case DARK_OAK_FENCE_GATE: - case OAK_FENCE_GATE: - case POWERED_RAIL: - return; - default:*/ Location location = BukkitUtil.getLocation(block.getLocation()); PlotArea area = location.getPlotArea(); if (area == null) { @@ -542,7 +381,6 @@ public class PlayerEvents extends PlotListener implements Listener { } event.setNewCurrent(0); } - //} } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @@ -940,27 +778,20 @@ public class PlayerEvents extends PlotListener implements Listener { } } if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { - switch (vehicle.getType()) { - case BOAT: - case ENDER_CRYSTAL: - case MINECART: - case MINECART_CHEST: - case MINECART_COMMAND: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: { - List meta = vehicle.getMetadata("plot"); - Plot toPlot = BukkitUtil.getLocation(to).getPlot(); - if (!meta.isEmpty()) { - Plot origin = (Plot) meta.get(0).value(); - if (!origin.getBasePlot(false).equals(toPlot)) { - vehicle.remove(); - } - } else if (toPlot != null) { - vehicle.setMetadata("plot", - new FixedMetadataValue((Plugin) PlotSquared.get().IMP, toPlot)); + final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(vehicle.getType()); + // Horses etc are vehicles, but they're also animals + // so this filters out all living entities + if (EntityCategories.VEHICLE.contains(entityType) && !EntityCategories.ANIMAL.contains(entityType)) { + List meta = vehicle.getMetadata("plot"); + Plot toPlot = BukkitUtil.getLocation(to).getPlot(); + if (!meta.isEmpty()) { + Plot origin = (Plot) meta.get(0).value(); + if (origin != null && !origin.getBasePlot(false).equals(toPlot)) { + vehicle.remove(); } + } else if (toPlot != null) { + vehicle.setMetadata("plot", + new FixedMetadataValue((Plugin) PlotSquared.get().IMP, toPlot)); } } } @@ -2672,29 +2503,41 @@ public class PlayerEvents extends PlotListener implements Listener { event.setCancelled(true); } } else if (!plot.isAdded(pp.getUUID())) { - Entity entity = event.getRightClicked(); - if (isMonster(entity) && plot.getFlag(HostileInteractFlag.class)) { + final Entity entity = event.getRightClicked(); + final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(entity.getType()); + + if (EntityCategories.HOSTILE.contains(entityType) && plot.getFlag(HostileInteractFlag.class)) { return; } - if ((entity instanceof Animals || entity instanceof Golem) && plot.getFlag(AnimalInteractFlag.class)) { + + if (EntityCategories.ANIMAL.contains(entityType) && plot.getFlag(AnimalInteractFlag.class)) { return; } + + // This actually makes use of the interface, so we don't use the + // category if (entity instanceof Tameable && ((Tameable) entity).isTamed() && plot .getFlag(TamedInteractFlag.class)) { return; } - if (entity instanceof Vehicle && plot.getFlag(VehicleUseFlag.class)) { + + if (EntityCategories.VEHICLE.contains(entityType) && plot.getFlag(VehicleUseFlag.class)) { return; } - if (entity instanceof Player && plot.getFlag(PlayerInteractFlag.class)) { + + if (EntityCategories.PLAYER.contains(entityType) && plot.getFlag(PlayerInteractFlag.class)) { return; } - if (entity instanceof Villager && plot.getFlag(VillagerInteractFlag.class)) { + + if (EntityCategories.VILLAGER.contains(entityType) && plot.getFlag(VillagerInteractFlag.class)) { return; } - if (entity instanceof ItemFrame && plot.getFlag(MiscInteractFlag.class)) { + + if ((EntityCategories.HANGING.contains(entityType) || + EntityCategories.OTHER.contains(entityType)) && plot.getFlag(MiscInteractFlag.class)) { return; } + if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_OTHER)) { MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, Captions.PERMISSION_ADMIN_INTERACT_OTHER); @@ -2897,7 +2740,9 @@ public class PlayerEvents extends PlotListener implements Listener { } if (player != null) { PlotPlayer plotPlayer = BukkitUtil.getPlayer(player); - if (victim instanceof Hanging) { // hanging + final com.sk89q.worldedit.world.entity.EntityType entityType = + BukkitAdapter.adapt(victim.getType()); + if (EntityCategories.HANGING.contains(entityType)) { // hanging if (plot != null && (plot.getFlag(HangingBreakFlag.class)) || plot .isAdded(plotPlayer.getUUID())) { if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) { @@ -2925,7 +2770,7 @@ public class PlayerEvents extends PlotListener implements Listener { "plots.admin.destroy." + stub); return false; } - } else if (isMonster(victim)) { + } else if (EntityCategories.HOSTILE.contains(entityType)) { if (plot != null && (plot.getFlag(HostileAttackFlag.class) || plot .getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { return true; @@ -2935,7 +2780,7 @@ public class PlayerEvents extends PlotListener implements Listener { "plots.admin.pve." + stub); return false; } - } else if (victim instanceof Tameable) { // victim is tameable + } else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable if (plot != null && (plot.getFlag(TamedAttackFlag.class) || plot .getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { return true; @@ -2945,7 +2790,7 @@ public class PlayerEvents extends PlotListener implements Listener { "plots.admin.pve." + stub); return false; } - } else if (victim instanceof Player) { + } else if (EntityCategories.PLAYER.contains(entityType)) { if (plot != null) { if (!plot.getFlag(PvpFlag.class) && !Permissions .hasPermission(plotPlayer, "plots.admin.pvp." + stub)) { @@ -2961,7 +2806,7 @@ public class PlayerEvents extends PlotListener implements Listener { "plots.admin.pvp." + stub); return false; } - } else if (victim instanceof Creature) { // victim is animal + } else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal if (plot != null && (plot.getFlag(AnimalAttackFlag.class) || plot .getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { return true; @@ -2971,7 +2816,7 @@ public class PlayerEvents extends PlotListener implements Listener { "plots.admin.pve." + stub); return false; } - } else if (victim instanceof Vehicle) { // Vehicles are managed in vehicle destroy event + } else if (EntityCategories.VEHICLE.contains(entityType)) { // Vehicles are managed in vehicle destroy event return true; } else { // victim is something else if (plot != null && (plot.getFlag(PveFlag.class) || plot @@ -3135,7 +2980,4 @@ public class PlayerEvents extends PlotListener implements Listener { } } - private boolean isMonster(Entity entity) { - return entity instanceof Monster || entity instanceof Boss || entity instanceof Slime; // :))) - } } From 5772af37fe1f63afd587e1306b5a62a94a71e44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 12 Apr 2020 04:46:51 +0200 Subject: [PATCH 3/4] Reclassify shulker as a hostile mob --- .../plotsquared/bukkit/util/BukkitUtil.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java index 38205b5e9..a834d5f25 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitUtil.java @@ -73,8 +73,8 @@ import org.bukkit.entity.Explosive; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Firework; import org.bukkit.entity.Ghast; -import org.bukkit.entity.Golem; import org.bukkit.entity.Hanging; +import org.bukkit.entity.IronGolem; import org.bukkit.entity.Item; import org.bukkit.entity.LightningStrike; import org.bukkit.entity.Monster; @@ -82,7 +82,9 @@ import org.bukkit.entity.NPC; import org.bukkit.entity.Phantom; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.Shulker; import org.bukkit.entity.Slime; +import org.bukkit.entity.Snowman; import org.bukkit.entity.Tameable; import org.bukkit.entity.Vehicle; import org.bukkit.entity.WaterMob; @@ -575,7 +577,8 @@ public class BukkitUtil extends WorldUtil { final Collection> allowedInterfaces = new HashSet<>(); switch (category) { case "animal": { - allowedInterfaces.add(Golem.class); + allowedInterfaces.add(IronGolem.class); + allowedInterfaces.add(Snowman.class); allowedInterfaces.add(Animals.class); allowedInterfaces.add(WaterMob.class); allowedInterfaces.add(Ambient.class); @@ -587,6 +590,7 @@ public class BukkitUtil extends WorldUtil { allowedInterfaces.add(Vehicle.class); } break; case "hostile": { + allowedInterfaces.add(Shulker.class); allowedInterfaces.add(Monster.class); allowedInterfaces.add(Boss.class); allowedInterfaces.add(Slime.class); From 79bd69e599b6482c7bea57e79032319c9696c8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 12 Apr 2020 19:30:50 +0200 Subject: [PATCH 4/4] Make the entity counting code use the new entity categories, remove usage of magic numbers and add `/plot caps` --- .../bukkit/util/BukkitChunkManager.java | 158 ++++-------------- .../plotsquared/plot/commands/Caps.java | 85 ++++++++++ .../plot/commands/MainCommand.java | 1 + .../plotsquared/plot/config/Caption.java | 7 +- .../plotsquared/plot/config/Captions.java | 7 + .../plotsquared/plot/object/Plot.java | 18 +- .../plotsquared/plot/util/EntityUtil.java | 19 ++- .../plot/util/entity/EntityCategories.java | 7 + 8 files changed, 157 insertions(+), 145 deletions(-) create mode 100644 Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Caps.java diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitChunkManager.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitChunkManager.java index 4258246ca..4e6085b71 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitChunkManager.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitChunkManager.java @@ -41,7 +41,9 @@ import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue; +import com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories; import com.github.intellectualsites.plotsquared.plot.util.world.RegionUtil; +import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -54,8 +56,6 @@ import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; -import org.bukkit.entity.Animals; -import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -71,6 +71,12 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Semaphore; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ANIMAL; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ENTITY; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MISC; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MOB; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MONSTER; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_VEHICLE; import static com.google.common.base.Preconditions.checkNotNull; public class BukkitChunkManager extends ChunkManager { @@ -514,135 +520,27 @@ public class BukkitChunkManager extends ChunkManager { } private void count(int[] count, Entity entity) { - switch (entity.getType()) { - case PLAYER: - // not valid - return; - case SMALL_FIREBALL: - case FIREBALL: - case DROPPED_ITEM: - case EGG: - case THROWN_EXP_BOTTLE: - case SPLASH_POTION: - case SNOWBALL: - case ENDER_PEARL: - case ARROW: - case TRIDENT: - case SHULKER_BULLET: - case SPECTRAL_ARROW: - case DRAGON_FIREBALL: - case LLAMA_SPIT: - // projectile - case PRIMED_TNT: - case FALLING_BLOCK: - // Block entities - case ENDER_CRYSTAL: - case FISHING_HOOK: - case ENDER_SIGNAL: - case EXPERIENCE_ORB: - case LEASH_HITCH: - case FIREWORK: - case LIGHTNING: - case WITHER_SKULL: - case UNKNOWN: - case AREA_EFFECT_CLOUD: - case EVOKER_FANGS: - // non moving / unremovable - break; - case ITEM_FRAME: - case PAINTING: - case ARMOR_STAND: - count[5]++; - break; - // misc - case MINECART: - case MINECART_CHEST: - case MINECART_COMMAND: - case MINECART_FURNACE: - case MINECART_HOPPER: - case MINECART_MOB_SPAWNER: - case MINECART_TNT: - case BOAT: - count[4]++; - break; - case POLAR_BEAR: - case RABBIT: - case SHEEP: - case MUSHROOM_COW: - case OCELOT: - case PIG: - case HORSE: - case SQUID: - case VILLAGER: - case IRON_GOLEM: - case WOLF: - case CHICKEN: - case COW: - case SNOWMAN: - case BAT: - case DONKEY: - case LLAMA: - case SKELETON_HORSE: - case ZOMBIE_HORSE: - case MULE: - case DOLPHIN: - case TURTLE: - case COD: - case PARROT: - case SALMON: - case PUFFERFISH: - case TROPICAL_FISH: - case CAT: - case FOX: - case PANDA: - // animal - count[3]++; - count[1]++; - break; - case BLAZE: - case CAVE_SPIDER: - case CREEPER: - case ENDERMAN: - case ENDERMITE: - case ENDER_DRAGON: - case GHAST: - case GIANT: - case GUARDIAN: - case MAGMA_CUBE: - case PIG_ZOMBIE: - case SILVERFISH: - case SKELETON: - case SLIME: - case SPIDER: - case WITCH: - case WITHER: - case ZOMBIE: - case SHULKER: - case ELDER_GUARDIAN: - case STRAY: - case HUSK: - case EVOKER: - case VEX: - case WITHER_SKELETON: - case ZOMBIE_VILLAGER: - case VINDICATOR: - // monster - count[3]++; - count[2]++; - break; - default: - if (entity instanceof Creature) { - count[3]++; - if (entity instanceof Animals) { - count[1]++; - } else { - count[2]++; - } - } else { - count[4]++; - } + final com.sk89q.worldedit.world.entity.EntityType entityType = + BukkitAdapter.adapt(entity.getType()); + + if (EntityCategories.PLAYER.contains(entityType)) { + return; + } else if (EntityCategories.PROJECTILE.contains(entityType) || + EntityCategories.OTHER.contains(entityType) || + EntityCategories.HANGING.contains(entityType)) { + count[CAP_MISC]++; + } else if (EntityCategories.ANIMAL.contains(entityType) || + EntityCategories.VILLAGER.contains(entityType) || + EntityCategories.TAMEABLE.contains(entityType)) { + count[CAP_MOB]++; + count[CAP_ANIMAL]++; + } else if (EntityCategories.VEHICLE.contains(entityType)) { + count[CAP_VEHICLE]++; + } else if (EntityCategories.HOSTILE.contains(entityType)) { + count[CAP_MOB]++; + count[CAP_MONSTER]++; } - count[0]++; + count[CAP_ENTITY]++; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Caps.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Caps.java new file mode 100644 index 000000000..bc47d3237 --- /dev/null +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Caps.java @@ -0,0 +1,85 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.github.intellectualsites.plotsquared.plot.commands; + +import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; +import com.github.intellectualsites.plotsquared.plot.config.Captions; +import com.github.intellectualsites.plotsquared.plot.flags.PlotFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalCapFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.EntityCapFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.HostileCapFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.MiscCapFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.MobCapFlag; +import com.github.intellectualsites.plotsquared.plot.flags.implementations.VehicleCapFlag; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; +import com.github.intellectualsites.plotsquared.plot.util.Permissions; + +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ANIMAL; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ENTITY; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MISC; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MOB; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MONSTER; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_VEHICLE; + +@CommandDeclaration(command = "caps", + category = CommandCategory.INFO, + description = "Show plot mob caps", + usage = "/plot caps") +public class Caps extends SubCommand { + + @Override public boolean onCommand(final PlotPlayer player, final String[] args) { + final Plot plot = player.getCurrentPlot(); + if (plot == null) { + return Captions.NOT_IN_PLOT.send(player); + } + if (!plot.isAdded(player.getUUID()) && !Permissions + .hasPermission(player, Captions.PERMISSION_ADMIN_CAPS_OTHER)) { + return Captions.NO_PERMISSION.send(player, Captions.PERMISSION_ADMIN_CAPS_OTHER); + } + Captions.PLOT_CAPS_HEADER.send(player); + 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); + return true; + } + + private > void sendFormatted(final Plot plot, + final PlotPlayer player, final Class capFlag, final int[] countedEntities, + final String name, final int type) { + final int current = countedEntities[type]; + final int max = plot.getFlag(capFlag); + final String percentage = String.format("%.1f", 100 * ((float) current / max)); + player.sendMessage(Captions.PLOT_CAPS_FORMAT.getTranslated().replace("%cap%", name) + .replace("%current%", Integer.toString(current)) + .replace("%limit%", Integer.toString(max)).replace("%percentage%", percentage)); + } + +} diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java index eb2b9f004..1b84f5000 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/MainCommand.java @@ -63,6 +63,7 @@ public class MainCommand extends Command { public static MainCommand getInstance() { if (instance == null) { instance = new MainCommand(); + new Caps(); new Buy(); new Save(); new Load(); diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Caption.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Caption.java index d85d31696..9b73590a9 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Caption.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Caption.java @@ -37,17 +37,18 @@ public interface Caption { return StringMan.replaceFromMap(getTranslated(), Captions.replacements); } - default void send(PlotPlayer caller, String... args) { - send(caller, (Object[]) args); + default boolean send(PlotPlayer caller, String... args) { + return send(caller, (Object[]) args); } - default void send(PlotPlayer caller, Object... args) { + default boolean send(PlotPlayer caller, Object... args) { String msg = CaptionUtility.format(caller, this, args); if (caller == null) { PlotSquared.log(msg); } else { caller.sendMessage(msg); } + return true; } boolean usePrefix(); diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Captions.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Captions.java index d29ebd668..d3358fdaf 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Captions.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/config/Captions.java @@ -83,6 +83,7 @@ public enum Captions implements Caption { PERMISSION_COMMANDS_CHAT("plots.admin.command.chat", "static.permissions"), PERMISSION_MERGE_OTHER("plots.merge.other", "static.permissions"), PERMISSION_MERGE_KEEP_ROAD("plots.merge.keeproad", "static.permissions"), + PERMISSION_ADMIN_CAPS_OTHER("plots.admin.caps.other", "static.permissions"), PERMISSION_ADMIN_DESTROY_UNOWNED("plots.admin.destroy.unowned", "static.permissions"), PERMISSION_ADMIN_DESTROY_GROUNDLEVEL("plots.admin.destroy.groundlevel", "static.permissions"), PERMISSION_ADMIN_DESTROY_OTHER("plots.admin.destroy.other", "static.permissions"), @@ -749,6 +750,12 @@ public enum Captions implements Caption { EVENT_DENIED("$1%s $2Cancelled by external plugin.", "Events"), // + // + PLOT_CAPS_HEADER("$3&m---------&r $1CAPS $3&m---------", false, "Info"), + PLOT_CAPS_FORMAT("$2- Cap Type: $1%cap% $2| Status: $1%current%$2/$1%limit% $2($1%percentage%%$2)", + false, "Info"), + // + /** * Legacy Configuration Conversion */ diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java index 8467ef0b2..7fe50edf6 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/object/Plot.java @@ -95,6 +95,12 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import static com.github.intellectualsites.plotsquared.plot.commands.SubCommand.sendMessage; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ANIMAL; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_VEHICLE; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ENTITY; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MISC; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MOB; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MONSTER; /** * The plot class
@@ -1278,12 +1284,12 @@ public class Plot { int[] count = new int[6]; for (Plot current : this.getConnectedPlots()) { int[] result = ChunkManager.manager.countEntities(current); - count[0] += result[0]; - count[1] += result[1]; - count[2] += result[2]; - count[3] += result[3]; - count[4] += result[4]; - count[5] += result[5]; + count[CAP_ENTITY] += result[CAP_ENTITY]; + count[CAP_ANIMAL] += result[CAP_ANIMAL]; + count[CAP_MONSTER] += result[CAP_MONSTER]; + count[CAP_MOB] += result[CAP_MOB]; + count[CAP_VEHICLE] += result[CAP_VEHICLE]; + count[CAP_MISC] += result[CAP_MISC]; } return count; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EntityUtil.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EntityUtil.java index 7b654100c..90c841c68 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EntityUtil.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/EntityUtil.java @@ -32,6 +32,13 @@ import com.github.intellectualsites.plotsquared.plot.object.Plot; import lombok.NonNull; import lombok.experimental.UtilityClass; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ANIMAL; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_ENTITY; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MISC; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MOB; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_MONSTER; +import static com.github.intellectualsites.plotsquared.plot.util.entity.EntityCategories.CAP_VEHICLE; + /** * Entity related general utility methods */ @@ -41,23 +48,23 @@ import lombok.experimental.UtilityClass; int i; switch (flagName) { case "mob-cap": - i = 3; + i = CAP_MOB; break; case "hostile-cap": - i = 2; + i = CAP_MONSTER; break; case "animal-cap": - i = 1; + i = CAP_ANIMAL; break; case "vehicle-cap": - i = 4; + i = CAP_VEHICLE; break; case "misc-cap": - i = 5; + i = CAP_MISC; break; case "entity-cap": default: - i = 0; + i = CAP_ENTITY; } return i; } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java index f40854cea..36ec700cd 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/entity/EntityCategories.java @@ -30,6 +30,13 @@ package com.github.intellectualsites.plotsquared.plot.util.entity; */ public class EntityCategories { + public static final int CAP_ENTITY = 0; + public static final int CAP_ANIMAL = 1; + public static final int CAP_MONSTER = 2; + public static final int CAP_MOB = 3; + public static final int CAP_VEHICLE = 4; + public static final int CAP_MISC = 5; + public static final EntityCategory ANIMAL = register("animal"); public static final EntityCategory TAMEABLE = register("tameable"); public static final EntityCategory VEHICLE = register("vehicle");