diff --git a/pom.xml b/pom.xml index 1346e681e..dedd99710 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ world.bentobox bentobox - 0.15.0 + 0.16.0-SNAPSHOT BentoBox BentoBox is an expandable Minecraft Spigot plugin for island-type games like ASkyBlock or AcidIsland. diff --git a/src/main/java/world/bentobox/bentobox/database/Database.java b/src/main/java/world/bentobox/bentobox/database/Database.java index f10ab3a9d..35f4d8d33 100644 --- a/src/main/java/world/bentobox/bentobox/database/Database.java +++ b/src/main/java/world/bentobox/bentobox/database/Database.java @@ -66,8 +66,11 @@ public class Database { try { result = handler.loadObject(uniqueId); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | ClassNotFoundException | IntrospectionException | NoSuchMethodException | SecurityException e) { + | ClassNotFoundException | IntrospectionException | SecurityException e) { logger.severe(() -> "Could not load object from database! " + e.getMessage()); + } catch (NoSuchMethodException e) { + logger.severe(() -> "Could not load object from database! " + e.getMessage()); + logger.severe(() -> "Did you forget the JavaBean no-arg default constructor?"); } return result; } diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java index 92286d45a..66ec372bd 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java @@ -491,19 +491,30 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { return Long.valueOf((Integer) value); } if (value.getClass().equals(String.class)) { - return deserializeGenericTypes((String) value, clazz); + if (clazz.equals(Integer.class)) { + return Integer.valueOf((String) value); + } + if (clazz.equals(Long.class)) { + return Long.valueOf((String) value); + } + if (clazz.equals(Double.class)) { + return Double.valueOf((String) value); + } + if (clazz.equals(Float.class)) { + return Float.valueOf((String) value); + } } if (clazz.equals(UUID.class)) { - return UUID.fromString((String)value); + value = UUID.fromString((String)value); } // Bukkit Types if (clazz.equals(Location.class)) { // Get Location from String - may be null... - return Util.getLocationString(((String)value)); + value = Util.getLocationString(((String)value)); } if (clazz.equals(World.class)) { // Get world by name - may be null... - return plugin.getServer().getWorld((String)value); + value = plugin.getServer().getWorld((String)value); } // Enums if (Enum.class.isAssignableFrom(clazz)) { @@ -511,7 +522,7 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { // Find out the value Class enumClass = (Class)clazz; try { - return Enum.valueOf(enumClass, (String)value); + value = Enum.valueOf(enumClass, ((String)value).toUpperCase()); } catch (Exception e) { // This value does not exist - probably admin typed it wrongly // Show what is available and pick one at random @@ -520,28 +531,12 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { for (Field fields : enumClass.getFields()) { plugin.logError(fields.getName()); } + value = null; } } - // Could not deserialize the value. return value; } - private Object deserializeGenericTypes(String value, Class clazz) { - if (clazz.equals(Integer.class)) { - return Integer.valueOf(value); - } - if (clazz.equals(Long.class)) { - return Long.valueOf(value); - } - if (clazz.equals(Double.class)) { - return Double.valueOf(value); - } - if (clazz.equals(Float.class)) { - return Float.valueOf(value); - } - return null; - } - /* (non-Javadoc) * @see world.bentobox.bentobox.database.AbstractDatabaseHandler#deleteObject(java.lang.Object) */ diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/BreedingListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/BreedingListener.java index dee3bbe66..10726ee75 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/BreedingListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/BreedingListener.java @@ -30,7 +30,8 @@ public class BreedingListener extends FlagListener { Material.EGG, Material.WHEAT, Material.CARROT, - Material.WHEAT_SEEDS); + Material.WHEAT_SEEDS, + Material.SEAGRASS); @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index 1b1259250..531d055f4 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -114,8 +114,12 @@ public class AddonsManager { private void loadAddon(File f) { Addon addon; - // try loading the addon - try (JarFile jar = new JarFile(f); AddonClassLoader addonClassLoader = new AddonClassLoader(this, addonDescription(jar), f, this.getClass().getClassLoader())) { + try (JarFile jar = new JarFile(f)) { + // try loading the addon + // Get description in the addon.yml file + YamlConfiguration data = addonDescription(jar); + // Load the addon + AddonClassLoader addonClassLoader = new AddonClassLoader(this, data, f, this.getClass().getClassLoader()); // Get the addon itself addon = addonClassLoader.getAddon(); // Initialize some settings diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/BreedingListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/BreedingListenerTest.java new file mode 100644 index 000000000..e93b4eef1 --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/BreedingListenerTest.java @@ -0,0 +1,297 @@ +/** + * + */ +package world.bentobox.bentobox.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.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +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.entity.Animals; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Zombie; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.PluginManager; +import org.bukkit.util.Vector; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; +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.configuration.WorldSettings; +import world.bentobox.bentobox.api.user.Notifier; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.FlagsManager; +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, Flags.class, Util.class} ) +public class BreedingListenerTest { + + private Location location; + private BentoBox plugin; + private Notifier notifier; + private Player player; + private PlayerInventory inventory; + private ItemStack itemInMainHand; + private ItemStack itemInOffHand; + private IslandWorldManager iwm; + + private static final List BREEDING_ITEMS = Arrays.asList( + Material.EGG, + Material.WHEAT, + Material.CARROT, + Material.WHEAT_SEEDS, + Material.SEAGRASS); + + @Before + public void setUp() { + // Set up plugin + plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + + Server server = mock(Server.class); + World 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); + //Bukkit.setServer(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.inWorld(any(World.class))).thenReturn(true); + when(iwm.inWorld(any(Location.class))).thenReturn(true); + when(plugin.getIWM()).thenReturn(iwm); + + // Monsters and animals + Zombie zombie = mock(Zombie.class); + when(zombie.getLocation()).thenReturn(location); + Slime slime = mock(Slime.class); + when(slime.getLocation()).thenReturn(location); + Cow cow = mock(Cow.class); + when(cow.getLocation()).thenReturn(location); + + // Fake players + Settings settings = mock(Settings.class); + Mockito.when(plugin.getSettings()).thenReturn(settings); + Mockito.when(settings.getFakePlayers()).thenReturn(new HashSet<>()); + + // Player and player inventory. Start with nothing in hands + player = mock(Player.class); + inventory = mock(PlayerInventory.class); + itemInMainHand = mock(ItemStack.class); + when(itemInMainHand.getType()).thenReturn(Material.AIR); + itemInOffHand = mock(ItemStack.class); + when(itemInOffHand.getType()).thenReturn(Material.AIR); + when(inventory.getItemInMainHand()).thenReturn(itemInMainHand); + when(inventory.getItemInOffHand()).thenReturn(itemInOffHand); + when(player.getInventory()).thenReturn(inventory); + User.setPlugin(plugin); + + // Locales + LocalesManager lm = mock(LocalesManager.class); + when(plugin.getLocalesManager()).thenReturn(lm); + Answer answer = invocation -> (String)Arrays.asList(invocation.getArguments()).get(1); + when(lm.get(any(), any())).thenAnswer(answer); + + // Player name + PlayersManager pm = mock(PlayersManager.class); + when(pm.getName(Mockito.any())).thenReturn("tastybento"); + when(plugin.getPlayers()).thenReturn(pm); + + // 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 + IslandsManager 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); + + // Notifier + notifier = mock(Notifier.class); + when(plugin.getNotifier()).thenReturn(notifier); + + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractNotAnimal() { + Entity clickedEntity = mock(Entity.class); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position); + new BreedingListener().onPlayerInteract(e); + assertFalse("Not animal failed", e.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalNothingInMainHand() { + + Animals clickedEntity = mock(Animals.class); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position); + new BreedingListener().onPlayerInteract(e); + assertFalse("Animal, nothing in main hand failed", e.isCancelled()); + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalNothingInOffHand() { + Animals clickedEntity = mock(Animals.class); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND); + new BreedingListener().onPlayerInteract(e); + assertFalse("Animal, nothing in off hand failed", e.isCancelled()); + } + + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalBreedingFoodInMainHandNotRightWorld() { + Animals clickedEntity = mock(Animals.class); + when(clickedEntity.getLocation()).thenReturn(location); + when(iwm.inWorld(any(World.class))).thenReturn(false); + when(iwm.inWorld(any(Location.class))).thenReturn(false); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position); + BreedingListener bl = new BreedingListener(); + for (Material breedingMat : BREEDING_ITEMS) { + when(itemInMainHand.getType()).thenReturn(breedingMat); + bl.onPlayerInteract(e); + assertFalse("Animal, breeding item in main hand, wrong world failed " + breedingMat, e.isCancelled()); + } + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalBreedingFoodInMainHand() { + Animals clickedEntity = mock(Animals.class); + when(clickedEntity.getLocation()).thenReturn(location); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position); + BreedingListener bl = new BreedingListener(); + for (Material breedingMat : BREEDING_ITEMS) { + when(itemInMainHand.getType()).thenReturn(breedingMat); + bl.onPlayerInteract(e); + assertTrue("Animal, breeding item in main hand failed " + breedingMat, e.isCancelled()); + } + } + + /** + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalBreedingFoodInOffHandNotRightWorld() { + Animals clickedEntity = mock(Animals.class); + when(clickedEntity.getLocation()).thenReturn(location); + when(iwm.inWorld(any(World.class))).thenReturn(false); + when(iwm.inWorld(any(Location.class))).thenReturn(false); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND); + BreedingListener bl = new BreedingListener(); + for (Material breedingMat : BREEDING_ITEMS) { + when(itemInOffHand.getType()).thenReturn(breedingMat); + bl.onPlayerInteract(e); + assertFalse("Animal, breeding item in off hand, wrong world failed " + breedingMat, e.isCancelled()); + } + } + + /** + * I am not sure if breeding with off hand is possible! + * Test method for {@link world.bentobox.bentobox.listeners.flags.BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}. + */ + @Test + public void testOnPlayerInteractAnimalBreedingFoodInOffHand() { + Animals clickedEntity = mock(Animals.class); + when(clickedEntity.getLocation()).thenReturn(location); + Vector position = new Vector(0,0,0); + PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND); + BreedingListener bl = new BreedingListener(); + for (Material breedingMat : BREEDING_ITEMS) { + when(itemInOffHand.getType()).thenReturn(breedingMat); + bl.onPlayerInteract(e); + assertTrue("Animal, breeding item in off hand failed " + breedingMat, e.isCancelled()); + } + } +} diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/PhysicalInteractionListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/PhysicalInteractionListenerTest.java index 8a89b3894..c0eaab910 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/PhysicalInteractionListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/PhysicalInteractionListenerTest.java @@ -1,5 +1,5 @@ /** - * + * */ package world.bentobox.bentobox.listeners.flags; @@ -70,9 +70,9 @@ import world.bentobox.bentobox.util.Util; @PrepareForTest( {BentoBox.class, Flags.class, Util.class, Bukkit.class} ) public class PhysicalInteractionListenerTest { - private static Location location; - private static BentoBox plugin; - private static Notifier notifier; + private Location location; + private BentoBox plugin; + private Notifier notifier; @Before public void setUp() { @@ -318,7 +318,7 @@ public class PhysicalInteractionListenerTest { @Test public void testOnProjectileHitProjectileBlockNull() { Projectile entity = mock(Projectile.class); - ProjectileSource source = (ProjectileSource) mock(Creeper.class); + ProjectileSource source = mock(Creeper.class); when(entity.getShooter()).thenReturn(source); Block block = null; EntityInteractEvent e = new EntityInteractEvent(entity, block); @@ -333,7 +333,7 @@ public class PhysicalInteractionListenerTest { @Test public void testOnProjectileHitProjectile() { Projectile entity = mock(Projectile.class); - ProjectileSource source = (ProjectileSource) mock(Creeper.class); + ProjectileSource source = mock(Creeper.class); when(entity.getShooter()).thenReturn(source); Block block = mock(Block.class); EntityInteractEvent e = new EntityInteractEvent(entity, block); @@ -348,7 +348,7 @@ public class PhysicalInteractionListenerTest { @Test public void testOnProjectileHitProjectileBlockNullPlayer() { Projectile entity = mock(Projectile.class); - ProjectileSource source = (ProjectileSource) mock(Player.class); + ProjectileSource source = mock(Player.class); when(entity.getShooter()).thenReturn(source); Block block = null; EntityInteractEvent e = new EntityInteractEvent(entity, block); @@ -367,7 +367,7 @@ public class PhysicalInteractionListenerTest { when(player.isOp()).thenReturn(false); when(player.getLocation()).thenReturn(location); User.getInstance(player); - ProjectileSource source = (ProjectileSource) player ; + ProjectileSource source = player ; when(entity.getShooter()).thenReturn(source); Block block = mock(Block.class); when(block.getLocation()).thenReturn(location);