From 71e79db0a9e25dd8d17050faaae5c7e6f182f7ba Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 21 Jul 2018 16:48:53 -0700 Subject: [PATCH] Added Enderman protection flags and tests. --- .../listeners/flags/EndermanListener.java | 59 ++++ .../us/tastybento/bskyblock/lists/Flags.java | 15 +- .../listeners/flags/EndermanListenerTest.java | 274 ++++++++++++++++++ 3 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 src/main/java/us/tastybento/bskyblock/listeners/flags/EndermanListener.java create mode 100644 src/test/java/us/tastybento/bskyblock/listeners/flags/EndermanListenerTest.java diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/EndermanListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/EndermanListener.java new file mode 100644 index 000000000..f7da1d7f1 --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/EndermanListener.java @@ -0,0 +1,59 @@ +/** + * + */ +package us.tastybento.bskyblock.listeners.flags; + +import org.bukkit.Material; +import org.bukkit.entity.Enderman; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.material.MaterialData; + +import us.tastybento.bskyblock.api.flags.AbstractFlagListener; +import us.tastybento.bskyblock.lists.Flags; + +/** + * Listens for Endermen + * For the {@link us.tastybento.bskyblock.lists.Flags#ENDERMAN_GRIEFING} + * and {@link us.tastybento.bskyblock.lists.Flags#CREEPER_GRIEFING} flags. + * @author tastybento + * + */ +public class EndermanListener extends AbstractFlagListener { + /** + * Allows or prevents enderman griefing + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onEndermanGrief(final EntityChangeBlockEvent e) { + if (!(e.getEntity() instanceof Enderman) || !getIWM().inWorld(e.getEntity().getLocation())) { + return; + } + if (!Flags.ENDERMAN_GRIEFING.isSetForWorld(e.getEntity().getWorld())) { + e.setCancelled(true); + } + } + + /** + * Drops the Enderman's block when he dies if he has one + * + * @param e - event + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onEndermanDeath(final EntityDeathEvent e) { + if (!(e.getEntity() instanceof Enderman) + || !getIWM().inWorld(e.getEntity().getLocation()) + || !Flags.ENDERMAN_DEATH_DROP.isSetForWorld(e.getEntity().getWorld())) { + return; + } + // Get the block the enderman is holding + Enderman ender = (Enderman) e.getEntity(); + MaterialData m = ender.getCarriedMaterial(); + if (m != null && !m.getItemType().equals(Material.AIR)) { + // Drop the item + e.getEntity().getWorld().dropItemNaturally(e.getEntity().getLocation(), m.toItemStack(1)); + } + } + +} diff --git a/src/main/java/us/tastybento/bskyblock/lists/Flags.java b/src/main/java/us/tastybento/bskyblock/lists/Flags.java index f838c9cfb..864484d5a 100644 --- a/src/main/java/us/tastybento/bskyblock/lists/Flags.java +++ b/src/main/java/us/tastybento/bskyblock/lists/Flags.java @@ -19,6 +19,7 @@ import us.tastybento.bskyblock.listeners.flags.CleanSuperFlatListener; import us.tastybento.bskyblock.listeners.flags.CreeperListener; import us.tastybento.bskyblock.listeners.flags.EggListener; import us.tastybento.bskyblock.listeners.flags.EnderChestListener; +import us.tastybento.bskyblock.listeners.flags.EndermanListener; import us.tastybento.bskyblock.listeners.flags.EnterExitListener; import us.tastybento.bskyblock.listeners.flags.EntityInteractListener; import us.tastybento.bskyblock.listeners.flags.FireListener; @@ -167,6 +168,15 @@ public class Flags { .listener(new EnderChestListener()) .build(); + public static final Flag ENDERMAN_GRIEFING = new FlagBuilder().id("ENDERMAN_GRIEFING").icon(Material.END_BRICKS) + .allowedByDefault(true).type(Type.WORLD_SETTING) + .listener(new EndermanListener()) + .build(); + + public static final Flag ENDERMAN_DEATH_DROP = new FlagBuilder().id("ENDERMAN_DEATH_DROP").icon(Material.END_ROD) + .allowedByDefault(true).type(Type.WORLD_SETTING) + .build(); + public static final Flag ENTER_EXIT_MESSAGES = new FlagBuilder().id("ENTER_EXIT_MESSAGES").icon(Material.DIRT).allowedByDefault(true).type(Type.WORLD_SETTING) .listener(new EnterExitListener()) .build(); @@ -200,11 +210,6 @@ public class Flags { */ public static final Flag CREEPER_GRIEFING = new FlagBuilder().id("CREEPER_GRIEFING").icon(Material.FIREWORK).type(Type.WORLD_SETTING) .allowedByDefault(false).build(); - /** - * Globally allows or disallows TNT explosion damage/pain. - */ - - /** * @return List of all the flags in this class diff --git a/src/test/java/us/tastybento/bskyblock/listeners/flags/EndermanListenerTest.java b/src/test/java/us/tastybento/bskyblock/listeners/flags/EndermanListenerTest.java new file mode 100644 index 000000000..a1614ba3d --- /dev/null +++ b/src/test/java/us/tastybento/bskyblock/listeners/flags/EndermanListenerTest.java @@ -0,0 +1,274 @@ +/** + * + */ +package us.tastybento.bskyblock.listeners.flags; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Slime; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.material.MaterialData; +import org.bukkit.plugin.PluginManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.Settings; +import us.tastybento.bskyblock.api.configuration.WorldSettings; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.lists.Flags; +import us.tastybento.bskyblock.managers.FlagsManager; +import us.tastybento.bskyblock.managers.IslandWorldManager; +import us.tastybento.bskyblock.managers.IslandsManager; +import us.tastybento.bskyblock.util.Util; + +/** + * Tests enderman related listeners + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest( {BSkyBlock.class, Flags.class, Util.class, Bukkit.class} ) +public class EndermanListenerTest { + + private static Location location; + private static BSkyBlock plugin; + private static IslandWorldManager iwm; + private static IslandsManager im; + private static World world; + private static Enderman enderman; + private static Slime slime; + + @Before + public void setUp() { + // Set up plugin + plugin = mock(BSkyBlock.class); + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); + + Server server = mock(Server.class); + world = mock(World.class); + when(server.getLogger()).thenReturn(Logger.getAnonymousLogger()); + when(server.getWorld("world")).thenReturn(world); + when(server.getVersion()).thenReturn("BSB_Mocking"); + + PluginManager pluginManager = mock(PluginManager.class); + when(server.getPluginManager()).thenReturn(pluginManager); + + ItemFactory itemFactory = mock(ItemFactory.class); + when(server.getItemFactory()).thenReturn(itemFactory); + + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getServer()).thenReturn(server); + + SkullMeta skullMeta = mock(SkullMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(skullMeta); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); + location = mock(Location.class); + when(location.getWorld()).thenReturn(world); + when(location.getBlockX()).thenReturn(0); + when(location.getBlockY()).thenReturn(0); + when(location.getBlockZ()).thenReturn(0); + PowerMockito.mockStatic(Flags.class); + + FlagsManager flagsManager = new FlagsManager(plugin); + when(plugin.getFlagsManager()).thenReturn(flagsManager); + + + // Worlds + iwm = mock(IslandWorldManager.class); + when(iwm.getBSBIslandWorld()).thenReturn(world); + when(iwm.getBSBNetherWorld()).thenReturn(world); + when(iwm.getBSBEndWorld()).thenReturn(world); + when(iwm.inWorld(any())).thenReturn(true); + when(plugin.getIWM()).thenReturn(iwm); + + // Monsters and animals + enderman = mock(Enderman.class); + when(enderman.getLocation()).thenReturn(location); + when(enderman.getWorld()).thenReturn(world); + when(enderman.getCarriedMaterial()).thenReturn(new MaterialData(Material.STONE)); + slime = mock(Slime.class); + when(slime.getLocation()).thenReturn(location); + + // Fake players + Settings settings = mock(Settings.class); + Mockito.when(plugin.getSettings()).thenReturn(settings); + Mockito.when(settings.getFakePlayers()).thenReturn(new HashSet()); + + // World Settings + WorldSettings ws = mock(WorldSettings.class); + when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws); + Map worldFlags = new HashMap<>(); + when(ws.getWorldFlags()).thenReturn(worldFlags); + + // Island manager + im = mock(IslandsManager.class); + when(plugin.getIslands()).thenReturn(im); + Island island = mock(Island.class); + Optional optional = Optional.of(island); + when(im.getProtectedIslandAt(Mockito.any())).thenReturn(optional); + + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); + // Not allowed to start + Flags.ENDERMAN_GRIEFING.setSetting(world, false); + // Allowed to start + Flags.ENDERMAN_DEATH_DROP.setSetting(world, true); + + } + + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanGrief(org.bukkit.event.entity.EntityChangeBlockEvent)}. + */ + @Test + public void testNotEnderman() { + EndermanListener listener = new EndermanListener(); + Block to = mock(Block.class); + Material block = Material.ACACIA_DOOR; + byte data = 0; + @SuppressWarnings("deprecation") + EntityChangeBlockEvent e = new EntityChangeBlockEvent(slime, to, block, data); + listener.onEndermanGrief(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanGrief(org.bukkit.event.entity.EntityChangeBlockEvent)}. + */ + @Test + public void testOnEndermanGriefWrongWorld() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + EndermanListener listener = new EndermanListener(); + Block to = mock(Block.class); + Material block = Material.ACACIA_DOOR; + byte data = 0; + @SuppressWarnings("deprecation") + EntityChangeBlockEvent e = new EntityChangeBlockEvent(enderman, to, block, data); + listener.onEndermanGrief(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanGrief(org.bukkit.event.entity.EntityChangeBlockEvent)}. + */ + @Test + public void testOnEndermanGriefAllowed() { + Flags.ENDERMAN_GRIEFING.setSetting(world, true); + EndermanListener listener = new EndermanListener(); + Block to = mock(Block.class); + Material block = Material.ACACIA_DOOR; + byte data = 0; + @SuppressWarnings("deprecation") + EntityChangeBlockEvent e = new EntityChangeBlockEvent(enderman, to, block, data); + listener.onEndermanGrief(e); + assertFalse(e.isCancelled()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanGrief(org.bukkit.event.entity.EntityChangeBlockEvent)}. + */ + @Test + public void testOnEndermanGrief() { + EndermanListener listener = new EndermanListener(); + Block to = mock(Block.class); + Material block = Material.ACACIA_DOOR; + byte data = 0; + @SuppressWarnings("deprecation") + EntityChangeBlockEvent e = new EntityChangeBlockEvent(enderman, to, block, data); + listener.onEndermanGrief(e); + assertTrue(e.isCancelled()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanDeath(org.bukkit.event.entity.EntityDeathEvent)}. + */ + @Test + public void testOnNotEndermanDeath() { + EndermanListener listener = new EndermanListener(); + EntityDeathEvent e = new EntityDeathEvent(slime, new ArrayList()); + listener.onEndermanDeath(e); + Mockito.verify(world, Mockito.never()).dropItemNaturally(Mockito.any(), Mockito.any()); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanDeath(org.bukkit.event.entity.EntityDeathEvent)}. + */ + @Test + public void testOnEndermanDeathCarryAir() { + when(enderman.getCarriedMaterial()).thenReturn(new MaterialData(Material.AIR)); + EndermanListener listener = new EndermanListener(); + EntityDeathEvent e = new EntityDeathEvent(enderman, new ArrayList()); + listener.onEndermanDeath(e); + Mockito.verify(world, Mockito.never()).dropItemNaturally(Mockito.any(), Mockito.any()); + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanDeath(org.bukkit.event.entity.EntityDeathEvent)}. + */ + @Test + public void testOnEndermanDeathNotInWorld() { + when(iwm.inWorld(Mockito.any())).thenReturn(false); + EndermanListener listener = new EndermanListener(); + EntityDeathEvent e = new EntityDeathEvent(enderman, new ArrayList()); + listener.onEndermanDeath(e); + Mockito.verify(world, Mockito.never()).dropItemNaturally(Mockito.any(), Mockito.any()); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanDeath(org.bukkit.event.entity.EntityDeathEvent)}. + */ + @Test + public void testOnEndermanDeathNoFlag() { + Flags.ENDERMAN_DEATH_DROP.setSetting(world, false); + EndermanListener listener = new EndermanListener(); + EntityDeathEvent e = new EntityDeathEvent(enderman, new ArrayList()); + listener.onEndermanDeath(e); + Mockito.verify(world, Mockito.never()).dropItemNaturally(Mockito.any(), Mockito.any()); + + } + + /** + * Test method for {@link us.tastybento.bskyblock.listeners.flags.EndermanListener#onEndermanDeath(org.bukkit.event.entity.EntityDeathEvent)}. + */ + @Test + public void testOnEndermanDeath() { + EndermanListener listener = new EndermanListener(); + EntityDeathEvent e = new EntityDeathEvent(enderman, new ArrayList()); + listener.onEndermanDeath(e); + Mockito.verify(world).dropItemNaturally(Mockito.any(), Mockito.any()); + + } + +}