Deleted FlyingMobEvents (duplicate of GeoLimitMobs)

And also fixed a code smell with metrics method names in IslandsManager
This commit is contained in:
Florian CUNY 2018-08-15 10:52:10 +02:00
parent 0a0d66eebf
commit 7815c837dd
4 changed files with 9 additions and 553 deletions

View File

@ -18,7 +18,6 @@ import world.bentobox.bentobox.listeners.JoinLeaveListener;
import world.bentobox.bentobox.listeners.NetherPortals;
import world.bentobox.bentobox.listeners.ObsidianToLava;
import world.bentobox.bentobox.listeners.PanelListenerManager;
import world.bentobox.bentobox.listeners.protection.FlyingMobEvents;
import world.bentobox.bentobox.managers.AddonsManager;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
@ -157,8 +156,6 @@ public class BentoBox extends JavaPlugin {
manager.registerEvents(new NetherPortals(this), this);
// Obsidian to lava helper
manager.registerEvents(new ObsidianToLava(this), this);
// Flying mobs protection
manager.registerEvents(new FlyingMobEvents(this), this);
// End dragon blocking
manager.registerEvents(new BlockEndDragon(this), this);
// Banned visitor commands
@ -196,8 +193,8 @@ public class BentoBox extends JavaPlugin {
@Override
public int getValue() {
int created = islandsManager.metrics_getCreatedCount();
islandsManager.metrics_setCreatedCount(0);
int created = islandsManager.metricsGetCreatedCount();
islandsManager.metricsSetCreatedCount(0);
return created;
}
});

View File

@ -1,159 +0,0 @@
package world.bentobox.bentobox.listeners.protection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Wither;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;
/**
* This class manages flying mobs. If they exist the spawned island's limits they will be removed.
*
* @author tastybento
*
*/
public class FlyingMobEvents implements Listener {
private BentoBox plugin;
private WeakHashMap<Entity, Island> mobSpawnInfo;
/**
* @param plugin - plugin object
*/
public FlyingMobEvents(BentoBox plugin) {
this.plugin = plugin;
mobSpawnInfo = new WeakHashMap<>();
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
Iterator<Entry<Entity, Island>> it = mobSpawnInfo.entrySet().iterator();
while (it.hasNext()) {
Entry<Entity, Island> entry = it.next();
if (entry.getKey() == null) {
it.remove();
} else {
if (entry.getKey() instanceof LivingEntity) {
if (!entry.getValue().inIslandSpace(entry.getKey().getLocation())) {
it.remove();
// Kill mob
LivingEntity mob = (LivingEntity)entry.getKey();
mob.setHealth(0);
entry.getKey().remove();
}
} else {
// Not living entity
it.remove();
}
}
}
}, 20L, 20L);
}
/**
* Track where the mob was created. This will determine its allowable movement zone.
* @param e - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onMobSpawn(CreatureSpawnEvent e) {
// Only cover withers in the island world
if (!plugin.getIWM().inWorld(e.getEntity().getLocation()) || !(e.getEntityType().equals(EntityType.WITHER)
|| e.getEntityType().equals(EntityType.BLAZE)
|| e.getEntityType().equals(EntityType.GHAST))) {
return;
}
// Store where this mob originated
plugin.getIslands().getIslandAt(e.getLocation()).ifPresent(island->mobSpawnInfo.put(e.getEntity(),island));
}
/**
* Protects entities exploding. However, I am not sure if this will ever be called as pre-explosions should prevent it.
* @param e - event
* @return true if cancelled
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public boolean onMobExplosion(EntityExplodeEvent e) {
// Only cover in the island world
if (e.getEntity() == null || !plugin.getIWM().inWorld(e.getEntity().getLocation())) {
return false;
}
if (mobSpawnInfo.containsKey(e.getEntity()) && !mobSpawnInfo.get(e.getEntity()).inIslandSpace(e.getLocation())) {
// Cancel the explosion and block damage
e.blockList().clear();
e.setCancelled(true);
return true;
}
return false;
}
/**
* Deal with pre-explosions
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public boolean onWitherExplode(ExplosionPrimeEvent e) {
// Only cover withers in the island world
if (!plugin.getIWM().inWorld(e.getEntity().getLocation()) || e.getEntity() == null) {
return false;
}
// The wither or wither skulls can both blow up
if (e.getEntityType() == EntityType.WITHER
&& mobSpawnInfo.containsKey(e.getEntity())
&& !mobSpawnInfo.get(e.getEntity()).inIslandSpace(e.getEntity().getLocation())) {
// Cancel the explosion
e.setCancelled(true);
return true;
} else if (e.getEntityType() == EntityType.WITHER_SKULL) {
// Get shooter
Projectile projectile = (Projectile)e.getEntity();
if (projectile.getShooter() instanceof Wither) {
Wither wither = (Wither)projectile.getShooter();
// Check the location
if (mobSpawnInfo.containsKey(wither) && !mobSpawnInfo.get(wither).inIslandSpace(e.getEntity().getLocation())) {
// Cancel the explosion
e.setCancelled(true);
return true;
}
}
}
return false;
}
/**
* Withers change blocks to air after they are hit (don't know why)
* This prevents this when the wither has been spawned by a visitor
* @param e - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onWitherChangeBlocks(EntityChangeBlockEvent e) {
// Only cover withers in the island world
if (e.getEntityType() != EntityType.WITHER || !plugin.getIWM().inWorld(e.getEntity().getLocation()) ) {
return;
}
if (mobSpawnInfo.containsKey(e.getEntity()) && !mobSpawnInfo.get(e.getEntity()).inIslandSpace(e.getEntity().getLocation())) {
// We know about this wither
// Cancel the block changes
e.setCancelled(true);
}
}
/**
* Clean up the hashmap. It's probably not needed, but just in case.
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public Island onMobDeath(EntityDeathEvent e) {
return mobSpawnInfo.remove(e.getEntity());
}
}

View File

@ -58,8 +58,6 @@ public class IslandsManager {
* This is not stored persistently and resets when the server starts
*/
private Map<World,Location> last;
// Metrics data
private int metrics_createdcount = 0;
// Island Cache
private IslandCache islandCache;
@ -67,6 +65,9 @@ public class IslandsManager {
// Async database saving semaphore
private boolean midSave;
// Metrics data
private int metricsCreatedCount = 0;
/**
* Islands Manager
* @param plugin - plugin
@ -623,12 +624,12 @@ public class IslandsManager {
return getIslandAt(loc).filter(i -> i.onIsland(loc)).map(i -> i.getMemberSet().contains(player.getUniqueId())).orElse(false);
}
public int metrics_getCreatedCount(){
return metrics_createdcount;
public int metricsGetCreatedCount(){
return metricsCreatedCount;
}
public void metrics_setCreatedCount(int count){
metrics_createdcount = count;
public void metricsSetCreatedCount(int count){
metricsCreatedCount = count;
}
/**

View File

@ -1,383 +0,0 @@
/**
*
*/
package world.bentobox.bentobox.listeners.protection;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
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.List;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Wither;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.scheduler.BukkitScheduler;
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 world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.LocalesManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.util.Util;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, BentoBox.class, User.class, Util.class })
public class FlyingMobEventsTest {
private BentoBox plugin;
private IslandsManager im;
private PlayersManager pm;
private BukkitScheduler sch;
private IslandWorldManager iwm;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
// Set up plugin
plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
// Settings
Settings s = mock(Settings.class);
when(plugin.getSettings()).thenReturn(s);
// Player
Player p = mock(Player.class);
// Sometimes use Mockito.withSettings().verboseLogging()
User user = mock(User.class);
when(user.isOp()).thenReturn(false);
UUID uuid = UUID.randomUUID();
UUID notUUID = UUID.randomUUID();
while(notUUID.equals(uuid)) {
notUUID = UUID.randomUUID();
}
when(user.getUniqueId()).thenReturn(uuid);
when(user.getPlayer()).thenReturn(p);
when(user.getName()).thenReturn("tastybento");
User.setPlugin(plugin);
// Player has island to begin with
im = mock(IslandsManager.class);
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true);
when(im.isOwner(Mockito.any(), Mockito.any())).thenReturn(true);
when(im.getTeamLeader(Mockito.any(), Mockito.any())).thenReturn(uuid);
when(plugin.getIslands()).thenReturn(im);
when(plugin.getPlayers()).thenReturn(pm);
// Server & Scheduler
sch = mock(BukkitScheduler.class);
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(sch);
// Locales
LocalesManager lm = mock(LocalesManager.class);
when(lm.get(Mockito.any(), Mockito.any())).thenReturn("mock translation");
when(plugin.getLocalesManager()).thenReturn(lm);
// Normally in world
Util.setPlugin(plugin);
// Worlds
iwm = mock(IslandWorldManager.class);
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.inWorld(any())).thenReturn(true);
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#FlyingMobEvents(world.bentobox.bentobox.BentoBox)}.
*/
@Test
public void testFlyingMobEvents() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
assertNotNull(fme);
Mockito.verify(sch).runTaskTimer(Mockito.eq(plugin), Mockito.any(Runnable.class), Mockito.eq(20L), Mockito.eq(20L));
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobSpawn(org.bukkit.event.entity.CreatureSpawnEvent)}.
*/
@Test
public void testOnMobSpawnNotInWorld() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
LivingEntity le = mock(LivingEntity.class);
CreatureSpawnEvent e = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
// Not in world
when(iwm.inWorld(any())).thenReturn(false);
fme.onMobSpawn(e);
Mockito.verify(im, Mockito.never()).getIslandAt(Mockito.any(Location.class));
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobSpawn(org.bukkit.event.entity.CreatureSpawnEvent)}.
*/
@Test
public void testOnMobSpawnInWorldWrongType() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
LivingEntity le = mock(LivingEntity.class);
when(le.getType()).thenReturn(EntityType.AREA_EFFECT_CLOUD);
CreatureSpawnEvent e = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(e);
Mockito.verify(im, Mockito.never()).getIslandAt(Mockito.any(Location.class));
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobSpawn(org.bukkit.event.entity.CreatureSpawnEvent)}.
*/
@Test
public void testOnMobSpawnInWorldCorrectType() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
LivingEntity le = mock(LivingEntity.class);
when(le.getLocation()).thenReturn(mock(Location.class));
Optional<Island> oi = Optional.of(mock(Island.class));
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(le.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent e = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(e);
Mockito.verify(im).getIslandAt(Mockito.any(Location.class));
// Blaze
when(le.getType()).thenReturn(EntityType.BLAZE);
e = new CreatureSpawnEvent(le, SpawnReason.NATURAL);
fme.onMobSpawn(e);
Mockito.verify(im, Mockito.times(2)).getIslandAt(Mockito.any(Location.class));
// Ghast
when(le.getType()).thenReturn(EntityType.GHAST);
e = new CreatureSpawnEvent(le, SpawnReason.NATURAL);
fme.onMobSpawn(e);
Mockito.verify(im, Mockito.times(3)).getIslandAt(Mockito.any(Location.class));
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnMobExplosionFail() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Entity, Location, list of Blocks, yield
EntityExplodeEvent e = new EntityExplodeEvent(null, null, null, 0);
// null entity
assertFalse(fme.onMobExplosion(e));
// Not in world
Entity ent = mock(Entity.class);
when(iwm.inWorld(any())).thenReturn(false);
e = new EntityExplodeEvent(ent, null, null, 0);
assertFalse(fme.onMobExplosion(e));
// Unknown entity (not in the list)
when(iwm.inWorld(any())).thenReturn(true);
assertFalse(fme.onMobExplosion(e));
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnMobExplosionOnIsland() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn an entity
LivingEntity le = mock(LivingEntity.class);
when(le.getLocation()).thenReturn(mock(Location.class));
Island island = mock(Island.class);
// Start with ghast exploding in island space
when(island.inIslandSpace(Mockito.any(Location.class))).thenReturn(true);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(le.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(cee);
// Make the wither explode
// Entity, Location, list of Blocks, yield
Block block = mock(Block.class);
// One block will be blown up by the wither
List<Block> affectedBlocks = new ArrayList<>();
affectedBlocks.add(block);
// Create event
EntityExplodeEvent e = new EntityExplodeEvent(le, mock(Location.class), affectedBlocks, 0);
// Nothing blocked
assertFalse(fme.onMobExplosion(e));
assertFalse(e.isCancelled());
assertFalse(e.blockList().isEmpty());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobExplosion(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnMobExplosionOffIsland() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn an entity
LivingEntity le = mock(LivingEntity.class);
when(le.getLocation()).thenReturn(mock(Location.class));
Island island = mock(Island.class);
// Ghast exploding outside of island space
when(island.inIslandSpace(Mockito.any(Location.class))).thenReturn(false);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(le.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(cee);
// Make the wither explode
// Entity, Location, list of Blocks, yield
Block block = mock(Block.class);
// One block will be blown up by the wither
List<Block> affectedBlocks = new ArrayList<>();
affectedBlocks.add(block);
// Create event
EntityExplodeEvent e = new EntityExplodeEvent(le, mock(Location.class), affectedBlocks, 0);
// Blocked
assertTrue(fme.onMobExplosion(e));
assertTrue(e.isCancelled());
assertTrue(e.blockList().isEmpty());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onWitherExplode(org.bukkit.event.entity.ExplosionPrimeEvent)}.
*/
@Test
public void testOnWitherExplode() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn an entity
LivingEntity le = mock(LivingEntity.class);
when(le.getLocation()).thenReturn(mock(Location.class));
Island island = mock(Island.class);
// Ghast exploding outside of island space
when(island.inIslandSpace(Mockito.any(Location.class))).thenReturn(false);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(le.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(le, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(cee);
// Make the wither explode
// Create event
ExplosionPrimeEvent e = new ExplosionPrimeEvent(le, 0, false);
// Blocked
assertTrue(fme.onWitherExplode(e));
assertTrue(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onWitherExplode(org.bukkit.event.entity.ExplosionPrimeEvent)}.
*/
@Test
public void testOnWitherSkullExplode() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn a wither
Wither wither = mock(Wither.class);
when(wither.getLocation()).thenReturn(mock(Location.class));
Island island = mock(Island.class);
// Ghast exploding outside of island space
when(island.inIslandSpace(Mockito.any(Location.class))).thenReturn(false);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(wither.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(wither, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(cee);
// Make the wither shoot a skull
Projectile skull = mock(Projectile.class);
when(skull.getType()).thenReturn(EntityType.WITHER_SKULL);
when(skull.getShooter()).thenReturn(wither);
// Create event
ExplosionPrimeEvent e = new ExplosionPrimeEvent(skull, 0, false);
// Blocked
assertTrue(fme.onWitherExplode(e));
assertTrue(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onWitherChangeBlocks(org.bukkit.event.entity.EntityChangeBlockEvent)}.
*/
@Test
public void testOnWitherChangeBlocks() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn a wither
Wither wither = mock(Wither.class);
when(wither.getLocation()).thenReturn(mock(Location.class));
Island island = mock(Island.class);
// Ghast exploding outside of island space
when(island.inIslandSpace(Mockito.any(Location.class))).thenReturn(false);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
// Wither
when(wither.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(wither, SpawnReason.BUILD_WITHER);
fme.onMobSpawn(cee);
// Create event
/**
*
* @param what the Entity causing the change
* @param block the block (before the change)
* @param to the future material being changed to
* @param data the future block data
* @deprecated Magic value
*/
EntityChangeBlockEvent e = new EntityChangeBlockEvent(wither, mock(Block.class), Material.AIR.createBlockData());
// Blocked
fme.onWitherChangeBlocks(e);
assertTrue(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.protection.FlyingMobEvents#onMobDeath(org.bukkit.event.entity.EntityDeathEvent)}.
*/
@Test
public void testOnMobDeath() {
FlyingMobEvents fme = new FlyingMobEvents(plugin);
// Spawn a wither
Wither wither = mock(Wither.class);
// Wither
when(wither.getType()).thenReturn(EntityType.WITHER);
CreatureSpawnEvent cee = new CreatureSpawnEvent(wither, SpawnReason.BUILD_WITHER);
Island island = mock(Island.class);
Optional<Island> oi = Optional.of(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oi);
fme.onMobSpawn(cee);
// Kill it
EntityDeathEvent e = new EntityDeathEvent(wither, null);
assertNotNull(fme.onMobDeath(e));
}
}