From d0355e8b9e677f7f11739c6d4400dcd0d707f1d9 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 15 Sep 2019 16:41:17 -0700 Subject: [PATCH 01/17] Listener was not registered using BentoBox API so caused reload issues. --- src/main/java/world/bentobox/warps/Warp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 7919dc1..a1b48e5 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -130,7 +130,7 @@ public class Warp extends Addon { warpSignsManager = new WarpSignsManager(this, this.getPlugin()); warpPanelManager = new WarpPanelManager(this); // Load the listener - getServer().getPluginManager().registerEvents(new WarpSignsListener(this), this.getPlugin()); + this.registerListener(new WarpSignsListener(this)); } } From 675f5791bd2390e951817c732e549c1a3ba8edbb Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 15 Sep 2019 16:41:26 -0700 Subject: [PATCH 02/17] Version 1.8.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a5fb3b..63cd4af 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ -LOCAL - 1.7.0 + 1.8.0 From bbc748aae37f5b6b96fa1505f71cc2881965a3a3 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 18 Sep 2019 16:48:38 -0700 Subject: [PATCH 03/17] Enabled formatting of warp sign text https://github.com/BentoBoxWorld/Warps/issues/48 --- src/main/java/world/bentobox/warps/Warp.java | 2 + .../bentobox/warps/WarpPanelManager.java | 2 +- .../bentobox/warps/WarpSignsManager.java | 23 ++++++---- .../world/bentobox/warps/config/Settings.java | 46 +++++++++++++++++++ src/main/resources/config.yml | 8 ++++ 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index a1b48e5..92ffa1e 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -155,7 +155,9 @@ public class Warp extends Addon { // Disable this.logError("WelcomeWarp settings could not load! Addon disabled."); this.setState(State.DISABLED); + return; } + settingsConfig.saveConfigObject(settings); } diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java index d25ceef..ab4fc30 100644 --- a/src/main/java/world/bentobox/warps/WarpPanelManager.java +++ b/src/main/java/world/bentobox/warps/WarpPanelManager.java @@ -30,7 +30,7 @@ public class WarpPanelManager { private PanelItem getPanelItem(World world, UUID warpOwner) { PanelItemBuilder pib = new PanelItemBuilder() - .name(addon.getPlugin().getPlayers().getName(warpOwner)) + .name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner)) .description(getSign(world, warpOwner)) .clickHandler((panel, clicker, click, slot) -> { { clicker.closeInventory(); diff --git a/src/main/java/world/bentobox/warps/WarpSignsManager.java b/src/main/java/world/bentobox/warps/WarpSignsManager.java index a4e695c..fc58302 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/WarpSignsManager.java @@ -86,7 +86,7 @@ public class WarpSignsManager { */ public boolean addWarp(final UUID playerUUID, final Location loc) { // Do not allow null players to set warps - if (playerUUID == null) { + if (playerUUID == null || loc == null) { return false; } // Check for warps placed in a location where there was a warp before @@ -148,7 +148,7 @@ public class WarpSignsManager { } // Fire event WarpListEvent event = new WarpListEvent(addon, list); - addon.getServer().getPluginManager().callEvent(event); + Bukkit.getPluginManager().callEvent(event); // Get the result of any changes by listeners list = event.getWarps(); return list; @@ -268,10 +268,13 @@ public class WarpSignsManager { result.remove(0); // Remove any trailing blank lines result.removeIf(String::isEmpty); + // Set the initial color per lore setting + for (int i = 0; i< result.size(); i++) { + result.set(i, ChatColor.translateAlternateColorCodes('&', addon.getSettings().getLoreFormat()) + result.get(i)); + } // Get the sign type - String prefix = this.plugin.getIWM().getAddon(world).map( - Addon::getPermissionPrefix).orElse(""); + String prefix = plugin.getIWM().getAddon(world).map(Addon::getPermissionPrefix).orElse(""); Material icon; @@ -394,7 +397,7 @@ public class WarpSignsManager { return; } - Island island = addon.getPlugin().getIslands().getIsland(world, owner); + Island island = addon.getIslands().getIsland(world, owner); boolean pvp = false; if (island != null) { // Check for PVP @@ -421,25 +424,25 @@ public class WarpSignsManager { Location inFront = b.getRelative(directionFacing).getLocation(); Location oneDown = b.getRelative(directionFacing).getRelative(BlockFace.DOWN).getLocation(); if ((plugin.getIslands().isSafeLocation(inFront))) { - addon.getWarpSignsManager().warpPlayer(user, inFront, owner, directionFacing, pvp); + warpPlayer(user, inFront, owner, directionFacing, pvp); return; } else if (plugin.getIslands().isSafeLocation(oneDown)) { // Try one block down if this is a wall sign - addon.getWarpSignsManager().warpPlayer(user, oneDown, owner, directionFacing, pvp); + warpPlayer(user, oneDown, owner, directionFacing, pvp); return; } } else if (b.getType().name().contains("SIGN")) { org.bukkit.block.data.type.Sign s = (org.bukkit.block.data.type.Sign) b.getBlockData(); BlockFace directionFacing = s.getRotation(); Location inFront = b.getRelative(directionFacing).getLocation(); - if ((plugin.getIslands().isSafeLocation(inFront))) { - addon.getWarpSignsManager().warpPlayer(user, inFront, owner, directionFacing, pvp); + if ((addon.getIslands().isSafeLocation(inFront))) { + warpPlayer(user, inFront, owner, directionFacing, pvp); return; } } else { // Warp has been removed user.sendMessage("warps.error.does-not-exist"); - addon.getWarpSignsManager().removeWarp(warpSpot); + removeWarp(warpSpot); return; } if (!(plugin.getIslands().isSafeLocation(warpSpot))) { diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java index 0b1e7ac..34943dd 100644 --- a/src/main/java/world/bentobox/warps/config/Settings.java +++ b/src/main/java/world/bentobox/warps/config/Settings.java @@ -44,7 +44,19 @@ public class Settings implements ConfigObject @ConfigComment(" - BSkyBlock") @ConfigEntry(path = "disabled-gamemodes") private Set disabledGameModes = new HashSet<>(); + + @ConfigComment("") + @ConfigComment("Warp panel name formatting.") + @ConfigComment("Example: &c will make names red. &f is white") + @ConfigEntry(path = "name-format") + private String nameFormat = "&f"; + @ConfigComment("") + @ConfigComment("Warp panel default lore formatting.") + @ConfigComment("Example: &c will make lore red. &f is white") + @ConfigEntry(path = "lore-format") + private String loreFormat = "&f"; + // --------------------------------------------------------------------- // Section: Constructor // --------------------------------------------------------------------- @@ -143,4 +155,38 @@ public class Settings implements ConfigObject { this.icon = icon; } + + + /** + * @return the nameFormat + */ + public String getNameFormat() { + return nameFormat; + } + + + /** + * @param nameFormat the nameFormat to set + */ + public void setNameFormat(String nameFormat) { + this.nameFormat = nameFormat; + } + + + /** + * @return the loreFormat + */ + public String getLoreFormat() { + return loreFormat; + } + + + /** + * @param loreFormat the loreFormat to set + */ + public void setLoreFormat(String loreFormat) { + this.loreFormat = loreFormat; + } + + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 93a29dc..f3679bf 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -23,3 +23,11 @@ icon: 'SIGN' # disabled-gamemodes: # - BSkyBlock disabled-gamemodes: [] +# +# Warp panel name formatting. +# Example: &c will make names red, &f is white +name-format: &f +# +# Warp panel default lore formatting. +# Example: &c will make lore red. &f is white +lore-format: &f From b98d83fffc999c1fa066e7bbe14e2892e59809cf Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 18 Sep 2019 16:48:54 -0700 Subject: [PATCH 04/17] Added WarpSignsManager test class --- .../bentobox/warps/WarpSignsManagerTest.java | 450 ++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 src/test/java/world/bentobox/warps/WarpSignsManagerTest.java diff --git a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java new file mode 100644 index 0000000..37c3456 --- /dev/null +++ b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java @@ -0,0 +1,450 @@ +package world.bentobox.warps; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.beans.IntrospectionException; +import java.lang.reflect.InvocationTargetException; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +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.api.user.User; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.DatabaseSetup; +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.PlaceholdersManager; +import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.bentobox.util.Util; +import world.bentobox.warps.config.Settings; +import world.bentobox.warps.event.WarpInitiateEvent; +import world.bentobox.warps.objects.WarpsData; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, Util.class, DatabaseSetup.class}) +public class WarpSignsManagerTest { + + @Mock + private Warp addon; + @Mock + private BentoBox plugin; + @Mock + private World world; + @Mock + private static AbstractDatabaseHandler handler; + + + private WarpSignsManager wsm; + @Mock + private Logger logger; + @Mock + private WarpsData load; + private UUID uuid = UUID.randomUUID(); + @Mock + private Location location; + @Mock + private Block block; + @Mock + private PluginManager pim; + @Mock + private Server server; + @Mock + private Player player; + @Mock + private WarpPanelManager wpm; + @Mock + private PlayersManager pm; + @Mock + private OfflinePlayer offlinePlayer; + @Mock + private Settings settings; + @Mock + private IslandWorldManager iwm; + @Mock + private IslandsManager im; + @Mock + private Island island; + + + @SuppressWarnings("unchecked") + @BeforeClass + public static void beforeClass() { + // This has to be done beforeClass otherwise the tests will interfere with each other + handler = mock(AbstractDatabaseHandler.class); + // Database + PowerMockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(any())).thenReturn(handler); + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + when(addon.getPlugin()).thenReturn(plugin); + when(addon.getLogger()).thenReturn(logger); + + // Player + when(player.getUniqueId()).thenReturn(uuid); + User.getInstance(player); + + // Locales + LocalesManager lm = mock(LocalesManager.class); + when(lm.get(Mockito.any(), Mockito.any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(plugin.getLocalesManager()).thenReturn(lm); + // Return the same string + PlaceholdersManager phm = mock(PlaceholdersManager.class); + when(phm.replacePlaceholders(any(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + + + // Server + when(addon.getServer()).thenReturn(server); + when(server.getPlayer(any(UUID.class))).thenReturn(player); + + // Util + PowerMockito.mockStatic(Util.class); + when(Util.getWorld(any())).thenAnswer((Answer) invocation -> invocation.getArgument(0, World.class)); + when(Util.sameWorld(any(), any())).thenReturn(true); + + // Location + when(location.getWorld()).thenReturn(world); + when(location.getBlock()).thenReturn(block); + when(location.getBlockX()).thenReturn(23); + when(location.getBlockY()).thenReturn(24); + when(location.getBlockZ()).thenReturn(25); + when(world.getEnvironment()).thenReturn(Environment.NORMAL); + + // Block + when(block.getType()).thenReturn(Material.ACACIA_SIGN); + when(block.getLocation()).thenReturn(location); + Sign sign = mock(Sign.class); + String[] lines = {"[Welcome]", "line2", "line3", "line4"}; + when(sign.getLines()).thenReturn(lines); + when(sign.getLine(anyInt())).thenReturn("[Welcome]"); + when(sign.getType()).thenReturn(Material.ACACIA_SIGN); + when(block.getState()).thenReturn(sign); + org.bukkit.block.data.type.Sign signBd = mock(org.bukkit.block.data.type.Sign.class); + when(signBd.getRotation()).thenReturn(BlockFace.EAST); + when(block.getBlockData()).thenReturn(signBd); + when(block.getRelative(any())).thenReturn(block); + + // Handler + when(handler.objectExists(eq("warps"))).thenReturn(true); + Map warpMap = Collections.singletonMap(location, uuid); + when(load.getWarpSigns()).thenReturn(warpMap); + when(handler.loadObject(anyString())).thenReturn(load); + + // Settings + when(addon.getSettings()).thenReturn(settings); + when(settings.getWelcomeLine()).thenReturn("[Welcome]"); + when(settings.getLoreFormat()).thenReturn("&f"); + when(settings.getIcon()).thenReturn("SIGN"); + + // Bukkit + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getPluginManager()).thenReturn(pim); + + // Players Manager + when(plugin.getPlayers()).thenReturn(pm); + when(pm.getName(eq(uuid))).thenReturn("tastybento"); + + // Offline player + when(server.getOfflinePlayer(any(UUID.class))).thenReturn(offlinePlayer); + when(offlinePlayer.getLastPlayed()).thenReturn(System.currentTimeMillis()); + + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock."); + + // Island Manager + when(addon.getIslands()).thenReturn(im); + when(im.getIsland(any(), any(UUID.class))).thenReturn(island); + when(im.isSafeLocation(any())).thenReturn(true); + + // WarpPanelManager + when(addon.getWarpPanelManager()).thenReturn(wpm); + + // User + + + wsm = new WarpSignsManager(addon, plugin); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + User.clearUsers(); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + */ + @Test + public void testGetWarpMap() { + assertFalse("Map is empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + */ + @Test + public void testGetWarpMapNullWorld() { + when(location.getWorld()).thenReturn(null); + wsm = new WarpSignsManager(addon, plugin); + assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + */ + @Test + public void testGetWarpMapWrongBlockType() { + when(block.getType()).thenReturn(Material.COAL_ORE); + wsm = new WarpSignsManager(addon, plugin); + assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + */ + @Test + public void testGetWarpMapNullLocation() { + Map warpMap = Collections.singletonMap(null, uuid); + when(load.getWarpSigns()).thenReturn(warpMap); + wsm = new WarpSignsManager(addon, plugin); + assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + * @throws Exception + */ + @Test + public void testGetWarpMapNullDatabaseObject() throws Exception { + when(handler.loadObject(anyString())).thenReturn(null); + wsm = new WarpSignsManager(addon, plugin); + assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}. + */ + @Test + public void testGetWarpMapNothingInDatabase() { + when(handler.objectExists(eq("warps"))).thenReturn(false); + wsm = new WarpSignsManager(addon, plugin); + assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#WarpSignsManager(world.bentobox.warps.Warp, world.bentobox.bentobox.BentoBox)}. + * @throws Exception + */ + @Test + public void testWarpSignsManager() throws Exception { + verify(logger).info("Loading warps..."); + verify(load).getWarpSigns(); + verify(block).getType(); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}. + */ + @Test + public void testAddWarpNullPlayer() { + assertFalse(wsm.addWarp(null, null)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}. + */ + @Test + public void testAddWarpNullLocation() { + assertFalse(wsm.addWarp(uuid, null)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}. + */ + @Test + public void testAddWarpReplaceOldSign() { + assertTrue(wsm.addWarp(uuid, location)); + verify(player).sendMessage("warps.sign-removed"); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}. + */ + @Test + public void testAddWarpReplaceOldSignDifferentPlayer() { + assertTrue(wsm.addWarp(UUID.randomUUID(), location)); + verify(player).sendMessage("warps.sign-removed"); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}. + */ + @Test + public void testAddWarp() { + Location loc = mock(Location.class); + assertTrue(wsm.addWarp(uuid, loc)); + verify(pim).callEvent(any(WarpInitiateEvent.class)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetWarpWorldWorld() { + assertNull(wsm.getWarp(mock(World.class), uuid)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetWarp() { + assertEquals(location, wsm.getWarp(world, uuid)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpOwner(org.bukkit.Location)}. + */ + @Test + public void testGetWarpOwner() { + assertEquals("tastybento", wsm.getWarpOwner(location)); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getSortedWarps(org.bukkit.World)}. + */ + @Test + public void testGetSortedWarps() { + assertEquals(1, wsm.getSortedWarps(world).size()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#listWarps(org.bukkit.World)}. + */ + @Test + public void testListWarps() { + assertEquals(1, wsm.listWarps(world).size()); + assertEquals(uuid, wsm.listWarps(world).toArray()[0]); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#removeWarp(org.bukkit.Location)}. + */ + @Test + public void testRemoveWarpLocation() { + wsm.removeWarp(location); + assertTrue(wsm.listWarps(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#removeWarp(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testRemoveWarpWorldUUID() { + wsm.removeWarp(world, uuid); + assertTrue(wsm.listWarps(world).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#saveWarpList()}. + * @throws IntrospectionException + * @throws InvocationTargetException + * @throws Exception + */ + @Test + public void testSaveWarpList() throws Exception { + wsm.saveWarpList(); + verify(handler, Mockito.atLeastOnce()).saveObject(any()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#getSignInfo(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetSignInfo() { + SignCache sc = wsm.getSignInfo(world, uuid); + assertEquals(Material.ACACIA_SIGN, sc.getType()); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#warpPlayer(org.bukkit.World, world.bentobox.bentobox.api.user.User, java.util.UUID)}. + */ + @Test + public void testWarpPlayer() { + Player p = mock(Player.class); + when(p.getUniqueId()).thenReturn(UUID.randomUUID()); + when(p.getWorld()).thenReturn(world); + when(p.getName()).thenReturn("tastybento"); + @Nullable + User u = User.getInstance(p); + wsm.warpPlayer(world, u, uuid); + verify(p).teleport(any(Location.class)); + verify(player).sendMessage("warps.player-warped"); + } + + /** + * Test method for {@link world.bentobox.warps.WarpSignsManager#hasWarp(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testHasWarp() { + assertTrue(wsm.hasWarp(world, uuid)); + assertFalse(wsm.hasWarp(mock(World.class), uuid)); + assertFalse(wsm.hasWarp(world, UUID.randomUUID())); + } + +} From 38c54961182ee2c44512c1e94da870bc23d117f6 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 19 Sep 2019 14:23:29 -0700 Subject: [PATCH 05/17] Added random warp button to warps panel https://github.com/BentoBoxWorld/Warps/issues/20 --- .../bentobox/warps/WarpPanelManager.java | 30 +++++++++++++++++-- .../world/bentobox/warps/config/Settings.java | 21 +++++++++++++ src/main/resources/config.yml | 4 +++ src/main/resources/locales/en-US.yml | 1 + 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java index ab4fc30..1a7f6a9 100644 --- a/src/main/java/world/bentobox/warps/WarpPanelManager.java +++ b/src/main/java/world/bentobox/warps/WarpPanelManager.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.UUID; import org.bukkit.Material; @@ -46,6 +47,19 @@ public class WarpPanelManager { } } + private PanelItem getRandomButton(World world, User user, UUID warpOwner) { + ///give @p minecraft:player_head{display:{Name:"{\"text\":\"Question Mark\"}"},SkullOwner:"MHF_Question"} 1 + return new PanelItemBuilder() + .name(addon.getSettings().getNameFormat() + user.getTranslation("warps.random")) + .clickHandler((panel, clicker, click, slot) -> { { + clicker.closeInventory(); + addon.getWarpSignsManager().warpPlayer(world, clicker, warpOwner); + return true; + } + }) + .icon(Material.END_CRYSTAL).build(); + } + private Material getSignIcon(World world, UUID warpOwner) { // Add the worlds if we haven't seen this before cachedSigns.putIfAbsent(world, new HashMap<>()); @@ -83,6 +97,12 @@ public class WarpPanelManager { */ public void showWarpPanel(World world, User user, int index) { List warps = new ArrayList<>(addon.getWarpSignsManager().getSortedWarps(world)); + UUID randomWarp = null; + // Add random UUID + if (!warps.isEmpty() && addon.getSettings().isRandomAllowed()) { + randomWarp = warps.get(new Random().nextInt(warps.size())); + warps.add(0, randomWarp); + } if (index < 0) { index = 0; } else if (index > (warps.size() / PANEL_MAX_SIZE)) { @@ -94,14 +114,18 @@ public class WarpPanelManager { int i = index * PANEL_MAX_SIZE; for (; i < (index * PANEL_MAX_SIZE + PANEL_MAX_SIZE) && i < warps.size(); i++) { - panelBuilder.item(getPanelItem(world, warps.get(i))); + if (i == 0 && randomWarp != null) { + panelBuilder.item(getRandomButton(world, user, randomWarp)); + } else { + panelBuilder.item(getPanelItem(world, warps.get(i))); + } } final int panelNum = index; // Add signs if (i < warps.size()) { // Next panelBuilder.item(new PanelItemBuilder() - .name("Next") + .name(user.getTranslation("warps.next")) .icon(new ItemStack(Material.STONE)) .clickHandler((panel, clicker, click, slot) -> { user.closeInventory(); @@ -112,7 +136,7 @@ public class WarpPanelManager { if (i > PANEL_MAX_SIZE) { // Previous panelBuilder.item(new PanelItemBuilder() - .name("Previous") + .name(user.getTranslation("warps.previous")) .icon(new ItemStack(Material.COBBLESTONE)) .clickHandler((panel, clicker, click, slot) -> { user.closeInventory(); diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java index 34943dd..87fc5f2 100644 --- a/src/main/java/world/bentobox/warps/config/Settings.java +++ b/src/main/java/world/bentobox/warps/config/Settings.java @@ -57,6 +57,11 @@ public class Settings implements ConfigObject @ConfigEntry(path = "lore-format") private String loreFormat = "&f"; + @ConfigComment("") + @ConfigComment("Allow random teleport - adds a button to the warp panel that goes to a random warp sign") + @ConfigEntry(path = "random-allowed") + private boolean randomAllowed = true; + // --------------------------------------------------------------------- // Section: Constructor // --------------------------------------------------------------------- @@ -189,4 +194,20 @@ public class Settings implements ConfigObject } + /** + * @return the randomAllowed + */ + public boolean isRandomAllowed() { + return randomAllowed; + } + + + /** + * @param randomAllowed the randomAllowed to set + */ + public void setRandomAllowed(boolean randomAllowed) { + this.randomAllowed = randomAllowed; + } + + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f3679bf..db7d030 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -31,3 +31,7 @@ name-format: &f # Warp panel default lore formatting. # Example: &c will make lore red. &f is white lore-format: &f +# +# Allow random teleport - adds a button to the warp panel that goes to a random warp sign +random-allowed: true + diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 4810a30..1593c51 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -23,6 +23,7 @@ warps: next: "&6Next page" player-warped: "&2[name] warped to your warp sign!" previous: "&6Previous page" + random: "&4Random Warp" sign-removed: "&CWarp sign removed!" success: "&ASuccess!" title: "Warp Signs" From f8243e3035171996587abbfcc0a1388113e971b4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 19 Sep 2019 14:45:15 -0700 Subject: [PATCH 06/17] Added test cases. --- .../bentobox/warps/WarpPanelManagerTest.java | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java b/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java index b555f2e..3e3e584 100644 --- a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java @@ -1,9 +1,12 @@ package world.bentobox.warps; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; @@ -23,6 +26,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -57,6 +61,8 @@ public class WarpPanelManagerTest { @Mock private Inventory top; private UUID uuid; + @Mock + private Settings settings; /** * @throws java.lang.Exception @@ -104,7 +110,6 @@ public class WarpPanelManagerTest { when(Bukkit.createInventory(any(), Mockito.anyInt(), any())).thenReturn(top); - Settings settings = mock(Settings.class); when(settings.getIcon()).thenReturn("SIGN"); when(addon.getSettings()).thenReturn(settings); @@ -133,11 +138,43 @@ public class WarpPanelManagerTest { */ @Test public void testShowWarpPanelFirst() { + ArgumentCaptor argument = ArgumentCaptor.forClass(ItemStack.class); WarpPanelManager wpm = new WarpPanelManager(addon); wpm.showWarpPanel(world, user, 0); verify(player).openInventory(Mockito.eq(top)); // Just next sign - verify(top, Mockito.times(53)).setItem(Mockito.anyInt(), Mockito.any(ItemStack.class)); + verify(top, Mockito.times(53)).setItem(Mockito.anyInt(),argument.capture()); + assertEquals(Material.STONE, argument.getAllValues().get(52).getType()); + } + + /** + * Test method for {@link WarpPanelManager#showWarpPanel(org.bukkit.World, world.bentobox.bbox.api.user.User, int)}. + */ + @Test + public void testShowWarpPanelFirstRandom() { + when(settings.isRandomAllowed()).thenReturn(true); + ArgumentCaptor argument = ArgumentCaptor.forClass(ItemStack.class); + WarpPanelManager wpm = new WarpPanelManager(addon); + wpm.showWarpPanel(world, user, 0); + verify(player).openInventory(Mockito.eq(top)); + // Check crystal + verify(top, Mockito.atLeastOnce()).setItem(anyInt(), argument.capture()); + assertEquals(Material.END_CRYSTAL, argument.getAllValues().get(0).getType()); + } + + /** + * Test method for {@link WarpPanelManager#showWarpPanel(org.bukkit.World, world.bentobox.bbox.api.user.User, int)}. + */ + @Test + public void testShowWarpPanelNoRandom() { + when(settings.isRandomAllowed()).thenReturn(false); + ArgumentCaptor argument = ArgumentCaptor.forClass(ItemStack.class); + WarpPanelManager wpm = new WarpPanelManager(addon); + wpm.showWarpPanel(world, user, 0); + verify(player).openInventory(Mockito.eq(top)); + // Check crystal + verify(top, Mockito.atLeastOnce()).setItem(anyInt(), argument.capture()); + assertFalse(argument.getAllValues().get(0).getType().equals(Material.END_CRYSTAL)); } /** @@ -145,11 +182,14 @@ public class WarpPanelManagerTest { */ @Test public void testShowWarpPanelMiddle() { + ArgumentCaptor argument = ArgumentCaptor.forClass(ItemStack.class); WarpPanelManager wpm = new WarpPanelManager(addon); wpm.showWarpPanel(world, user, 1); verify(player).openInventory(Mockito.eq(top)); // includes previous and next signs - verify(top, Mockito.times(54)).setItem(Mockito.anyInt(), Mockito.any(ItemStack.class)); + verify(top, Mockito.times(54)).setItem(Mockito.anyInt(), argument.capture()); + assertEquals(Material.STONE, argument.getAllValues().get(52).getType()); + assertEquals(Material.COBBLESTONE, argument.getAllValues().get(53).getType()); } /** @@ -157,11 +197,13 @@ public class WarpPanelManagerTest { */ @Test public void testShowWarpPanelLast() { + ArgumentCaptor argument = ArgumentCaptor.forClass(ItemStack.class); WarpPanelManager wpm = new WarpPanelManager(addon); wpm.showWarpPanel(world, user, 3); verify(player).openInventory(Mockito.eq(top)); // Final amount, just previous sign - verify(top, Mockito.times(46)).setItem(Mockito.anyInt(), Mockito.any(ItemStack.class)); + verify(top, Mockito.times(46)).setItem(Mockito.anyInt(), argument.capture()); + assertEquals(Material.COBBLESTONE, argument.getAllValues().get(45).getType()); } /** From 0f00c7bd5219b5886c82c49fcf25b3ecdee63bad Mon Sep 17 00:00:00 2001 From: BONNe Date: Fri, 20 Sep 2019 03:08:35 +0300 Subject: [PATCH 07/17] Translate lv.yml via GitLocalize (#50) --- src/main/resources/locales/lv.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/locales/lv.yml b/src/main/resources/locales/lv.yml index edae7c4..57070e5 100644 --- a/src/main/resources/locales/lv.yml +++ b/src/main/resources/locales/lv.yml @@ -9,10 +9,10 @@ warps: does-not-exist: "&cAk vai! Uzaicinājuma zīme vairāk neeksistē!" no-permission: "&CTev nav nepieciešamās atļaujas, lai veiktu darbību!" no-remove: "&CTu nevari noņemt šo zīmi!" - no-warps-yet: "&CNav neviena aktīva uzaicinājuma zīme." not-enough-level: "&CTavas salas līmenis ir pārāk zems!" not-on-island: "&CTev ir jāatrodas uz savas salas, lai veiktu šo darbību!" not-safe: "&cŠī uzaicinājuma zīme nav droša!" + no-warps-yet: "&CNav neviena aktīva uzaicinājuma zīme." your-level-is: "&cTavas salas līmenis ir tikai [level], bet ir nepieciešams vismaz [required]. Vari mēģināt pārrēķināt savas salas līmeni." help: @@ -25,3 +25,4 @@ warps: title: Uzaicinājuma Zīmes warpTip: "&6Novieto zīmi ar tekstu [text] pirmajā rindā" warpToPlayersSign: "&6Pārvietojās uz [player] uzaicinājuma zīmes" + random: "&4Nejauša Zīmes Izvēle" From 5ee1520d8b530fd42f276076a927af2f7a0ae600 Mon Sep 17 00:00:00 2001 From: DuckSoft Date: Fri, 20 Sep 2019 22:14:47 +0800 Subject: [PATCH 08/17] Translate zh-CN.yml via GitLocalize (#51) --- src/main/resources/locales/zh-CN.yml | 31 ++++++++++++---------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml index 111b1c1..88601b2 100644 --- a/src/main/resources/locales/zh-CN.yml +++ b/src/main/resources/locales/zh-CN.yml @@ -1,32 +1,27 @@ -########################################################################################### -# 本文件是 YML 格式的文件. 编辑时请务必小心. # -# 请在 http://yaml-online-parser.appspot.com 等 YAML 检查器中检查您的编辑. # -########################################################################################### - -warp: - help: +--- +warp: + help: description: 传送到该玩家的传送木牌处 - parameters: <玩家名称> + parameters: "" warps: - deactivate: "&c禁用的旧转移标志!" - error: - does-not-exist: "&c转移不再存在!" + error: no-permission: "&C权限不足!" no-remove: "&C无权移除传送木牌!" - no-warps-yet: "&C暂无可用传送木牌" not-enough-level: "&C岛屿等级不够高!" - not-on-island: "&C操作必须在空岛上进行!" - not-safe: "&c转移不安全!" + no-warps-yet: "&C暂无可用传送木牌" your-level-is: "&c岛屿当前等级 [level], 需要等级 [required]" - help: + does-not-exist: "&c那个传送已经不存在了!" + not-on-island: "&C操作必须在你的岛屿上进行!" + not-safe: "&c那个传送不安全!" + help: description: 打开传送面板 next: "&6下一页" - player-warped: "&2[name]转移到你的标志!" previous: "&6上一页" sign-removed: "&C传送木牌已移除!" success: "&A成功!" title: 传送木牌 warpTip: "&6放置一个第一行是 [text] 的木牌以创建传送木牌" warpToPlayersSign: "&6正传送到 [player] 的传送木牌" - - + deactivate: "&c旧传送牌已不再使用!" + player-warped: "&2[name] 刚刚传送到了你的传送牌!" + random: "&4随机传送" From 197957648bb045ceba1e79d5f866ac8c0d4f8053 Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2019 22:11:56 -0700 Subject: [PATCH 09/17] Translate fr.yml via GitLocalize (#55) --- src/main/resources/locales/fr.yml | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/main/resources/locales/fr.yml b/src/main/resources/locales/fr.yml index eb2a4d2..0fcee35 100644 --- a/src/main/resources/locales/fr.yml +++ b/src/main/resources/locales/fr.yml @@ -1,30 +1,28 @@ -########################################################################################### -# This is a YML file. Be careful when editing. Check your edits in a YAML checker like # -# the one at http://yaml-online-parser.appspot.com # -########################################################################################### - -warp: - help: - description: "te téléporte au Warp d'un autre joueur" - parameters: -warps: +--- +warp: + help: + description: te téléporte au Warp d'un autre joueur + parameters: "" +warps: deactivate: "&cAncien panneau de Warp désactivé !" - error: + error: does-not-exist: "&cCe Warp n'existe plus !" no-permission: "&cVous n'avez pas la permission pour faire cela !" no-remove: "&cVous ne pouvez pas supprimer ce panneau !" - no-warps-yet: "&cIl n'y a encore aucun Warp sur ce serveur." - not-enough-level: "&cVotre niveau d'île n'est pas assez élevé pour faire cela !" + not-enough-level: "&cVotre niveau d'île n'est pas assez élevé pour faire cela + !" not-on-island: "&cVous devez être sur votre île pour faire cela !" not-safe: "&cCe Warp n'est pas sûr!" + no-warps-yet: "&cIl n'y a encore aucun Warp sur ce serveur." your-level-is: "&cVotre île est seulement niveau [level] et doit être niveau [required]." - help: - description: "Ouvre le menu des Warps" + help: + description: Ouvre le menu des Warps next: "&6Page suivante" player-warped: "&2[name] s'est téléporté sur votre île !" previous: "&6Page précédente" sign-removed: "&cPanneau de Warp supprimé !" success: "&aSuccès !" - title: "Panneau Warp" + title: Panneau Warp warpTip: "&6Placez un panneau et écrivez [text] sur la première ligne." warpToPlayersSign: "&6Téléportation sur l'île de [player]..." + random: "&4Warp aléatoire" From afb03e6d42e865ba9c67970622a7cd8bcb3959eb Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 10:09:33 -0700 Subject: [PATCH 10/17] Enables warps to operate in any world. Commands can be changed. https://github.com/BentoBoxWorld/Warps/issues/53 https://github.com/BentoBoxWorld/Warps/issues/54 --- src/main/java/world/bentobox/warps/Warp.java | 11 ++- .../bentobox/warps/WarpSignsListener.java | 36 +++++----- .../bentobox/warps/WarpSignsManager.java | 2 +- .../bentobox/warps/commands/WarpCommand.java | 21 ++++-- .../bentobox/warps/commands/WarpsCommand.java | 23 ++++--- .../world/bentobox/warps/config/Settings.java | 67 ++++++++++++++++++- src/main/resources/config.yml | 8 ++- .../bentobox/warps/WarpSignsListenerTest.java | 47 ++++++++++++- 8 files changed, 175 insertions(+), 40 deletions(-) diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 92ffa1e..e38f438 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -78,7 +78,11 @@ public class Warp extends Addon { // Save default config.yml this.saveDefaultConfig(); // Load the plugin's config - this.loadSettings(); + if (this.loadSettings()) { + // Load the master warp and warps command + new WarpCommand(this); + new WarpsCommand(this); + } } @@ -146,7 +150,7 @@ public class Warp extends Addon { /** * This method loads addon configuration settings in memory. */ - private void loadSettings() { + private boolean loadSettings() { if (settingsConfig == null) { settingsConfig = new Config<>(this, Settings.class); } @@ -155,9 +159,10 @@ public class Warp extends Addon { // Disable this.logError("WelcomeWarp settings could not load! Addon disabled."); this.setState(State.DISABLED); - return; + return false; } settingsConfig.saveConfigObject(settings); + return true; } diff --git a/src/main/java/world/bentobox/warps/WarpSignsListener.java b/src/main/java/world/bentobox/warps/WarpSignsListener.java index 9e2bcd2..74e7493 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/WarpSignsListener.java @@ -51,7 +51,8 @@ public class WarpSignsListener implements Listener { if (!e.getBlock().getType().name().contains("SIGN")) { return; } - if (!addon.inRegisteredWorld(b.getWorld())) { + if ((addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.inRegisteredWorld(b.getWorld())) + || (!addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.getSettings().isAllowInOtherWorlds()) ) { return; } User user = User.getInstance(e.getPlayer()); @@ -87,7 +88,8 @@ public class WarpSignsListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onSignWarpCreate(SignChangeEvent e) { Block b = e.getBlock(); - if (!addon.inRegisteredWorld(b.getWorld())) { + if ((addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.inRegisteredWorld(b.getWorld())) + || (!addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.getSettings().isAllowInOtherWorlds()) ) { return; } String title = e.getLine(0); @@ -100,21 +102,23 @@ public class WarpSignsListener implements Listener { user.sendMessage("general.errors.no-permission", "[permission]", addon.getPermPrefix(b.getWorld()) + "island.addwarp"); return; } - // Get level if level addon is available - Long level = addon.getLevel(Util.getWorld(b.getWorld()), user.getUniqueId()); - if (level != null && level < addon.getSettings().getWarpLevelRestriction()) { - user.sendMessage("warps.error.not-enough-level"); - user.sendMessage("warps.error.your-level-is", - "[level]", String.valueOf(level), - "[required]", String.valueOf(addon.getSettings().getWarpLevelRestriction())); - return; - } + if (addon.getPlugin().getIWM().inWorld(b.getWorld())) { + // Get level if level addon is available + Long level = addon.getLevel(Util.getWorld(b.getWorld()), user.getUniqueId()); + if (level != null && level < addon.getSettings().getWarpLevelRestriction()) { + user.sendMessage("warps.error.not-enough-level"); + user.sendMessage("warps.error.your-level-is", + "[level]", String.valueOf(level), + "[required]", String.valueOf(addon.getSettings().getWarpLevelRestriction())); + return; + } - // Check that the player is on their island - if (!(plugin.getIslands().userIsOnIsland(b.getWorld(), user))) { - user.sendMessage("warps.error.not-on-island"); - e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); - return; + // Check that the player is on their island + if (!(plugin.getIslands().userIsOnIsland(b.getWorld(), user))) { + user.sendMessage("warps.error.not-on-island"); + e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); + return; + } } // Check if the player already has a sign final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId()); diff --git a/src/main/java/world/bentobox/warps/WarpSignsManager.java b/src/main/java/world/bentobox/warps/WarpSignsManager.java index fc58302..9b4bc72 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/WarpSignsManager.java @@ -70,7 +70,7 @@ public class WarpSignsManager { public WarpSignsManager(Warp addon, BentoBox plugin) { this.addon = addon; this.plugin = plugin; - // Set up the database handler to store and retrieve Island classes + // Set up the database handler // Note that these are saved by the BSkyBlock database handler = new Database<>(addon, WarpsData.class); // Load the warps diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index 1a51b4c..ae9dc9c 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -6,6 +6,8 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; +import org.bukkit.World; + import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.warps.Warp; @@ -19,15 +21,22 @@ import world.bentobox.warps.Warp; public class WarpCommand extends CompositeCommand { private Warp addon; + private String perm = "island"; public WarpCommand(Warp addon, CompositeCommand bsbIslandCmd) { - super(bsbIslandCmd, "warp"); + super(bsbIslandCmd, addon.getSettings().getWarpCommand()); this.addon = addon; } + public WarpCommand(Warp addon) { + super(addon.getSettings().getWarpCommand()); + this.addon = addon; + perm = "welcomewarpsigns"; + } + @Override public void setup() { - this.setPermission("island.warp"); + this.setPermission(perm + ".warp"); this.setOnlyPlayer(true); this.setParametersHelp("warp.help.parameters"); this.setDescription("warp.help.description"); @@ -35,9 +44,10 @@ public class WarpCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { + World world = getWorld() == null ? user.getWorld() : getWorld(); if (args.size() == 1) { // Warp somewhere command - Set warpList = addon.getWarpSignsManager().listWarps(getWorld()); + Set warpList = addon.getWarpSignsManager().listWarps(world); if (warpList.isEmpty()) { user.sendMessage("warps.error.no-warps-yet"); user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); @@ -51,7 +61,7 @@ public class WarpCommand extends CompositeCommand { return false; } else { // Warp exists! - addon.getWarpSignsManager().warpPlayer(getWorld(), user, foundWarp); + addon.getWarpSignsManager().warpPlayer(world, user, foundWarp); return true; } } @@ -62,8 +72,9 @@ public class WarpCommand extends CompositeCommand { @Override public Optional> tabComplete(User user, String alias, List args) { + World world = getWorld() == null ? user.getWorld() : getWorld(); List options = new ArrayList<>(); - final Set warpList = addon.getWarpSignsManager().listWarps(getWorld()); + final Set warpList = addon.getWarpSignsManager().listWarps(world); for (UUID warp : warpList) { options.add(addon.getPlugin().getPlayers().getName(warp)); diff --git a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java index c547e3b..dec8412 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java @@ -1,33 +1,39 @@ -/** - * - */ package world.bentobox.warps.commands; import java.util.List; +import org.bukkit.World; + import world.bentobox.warps.Warp; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; /** - * @author ben + * @author tastybento * */ public class WarpsCommand extends CompositeCommand { private Warp addon; + private String perm = "island"; public WarpsCommand(Warp addon, CompositeCommand bsbIslandCmd) { - super(bsbIslandCmd, "warps"); + super(bsbIslandCmd, addon.getSettings().getWarpsCommand()); this.addon = addon; } + public WarpsCommand(Warp addon) { + super(addon.getSettings().getWarpsCommand()); + this.addon = addon; + perm = "welcomewarpsigns"; + } + /* (non-Javadoc) * @see us.tastybento.bskyblock.api.commands.BSBCommand#setup() */ @Override public void setup() { - this.setPermission("island.warp"); + this.setPermission(perm + ".warp"); this.setOnlyPlayer(true); this.setDescription("warps.help.description"); } @@ -37,11 +43,12 @@ public class WarpsCommand extends CompositeCommand { */ @Override public boolean execute(User user, String label, List args) { - if (addon.getWarpSignsManager().listWarps(getWorld()).isEmpty()) { + World world = getWorld() == null ? user.getWorld() : getWorld(); + if (addon.getWarpSignsManager().listWarps(world).isEmpty()) { user.sendMessage("warps.error.no-warps-yet"); user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); } else { - addon.getWarpPanelManager().showWarpPanel(getWorld(), user,0); + addon.getWarpPanelManager().showWarpPanel(world, user,0); } return true; } diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java index 87fc5f2..7b51024 100644 --- a/src/main/java/world/bentobox/warps/config/Settings.java +++ b/src/main/java/world/bentobox/warps/config/Settings.java @@ -44,7 +44,7 @@ public class Settings implements ConfigObject @ConfigComment(" - BSkyBlock") @ConfigEntry(path = "disabled-gamemodes") private Set disabledGameModes = new HashSet<>(); - + @ConfigComment("") @ConfigComment("Warp panel name formatting.") @ConfigComment("Example: &c will make names red. &f is white") @@ -56,12 +56,25 @@ public class Settings implements ConfigObject @ConfigComment("Example: &c will make lore red. &f is white") @ConfigEntry(path = "lore-format") private String loreFormat = "&f"; - + @ConfigComment("") @ConfigComment("Allow random teleport - adds a button to the warp panel that goes to a random warp sign") @ConfigEntry(path = "random-allowed") private boolean randomAllowed = true; - + + @ConfigComment("") + @ConfigComment("Allow use in other worlds. Players must have the welcomewarpsigns.warp permission.") + @ConfigEntry(path = "allow-in-other-worlds") + private boolean allowInOtherWorlds = false; + + @ConfigComment("") + @ConfigComment("Warp and warps commands. You can change them if they clash with other addons or plugins.") + @ConfigEntry(path = "warp-command") + String warpCommand = "warp"; + @ConfigEntry(path = "warps-command") + String warpsCommand = "warps"; + + // --------------------------------------------------------------------- // Section: Constructor // --------------------------------------------------------------------- @@ -210,4 +223,52 @@ public class Settings implements ConfigObject } + /** + * @return the allowInOtherWorlds + */ + public boolean isAllowInOtherWorlds() { + return allowInOtherWorlds; + } + + + /** + * @param allowInOtherWorlds the allowInOtherWorlds to set + */ + public void setAllowInOtherWorlds(boolean allowInOtherWorlds) { + this.allowInOtherWorlds = allowInOtherWorlds; + } + + + /** + * @return the warpCommand + */ + public String getWarpCommand() { + return warpCommand; + } + + + /** + * @param warpCommand the warpCommand to set + */ + public void setWarpCommand(String warpCommand) { + this.warpCommand = warpCommand; + } + + + /** + * @return the warpsCommand + */ + public String getWarpsCommand() { + return warpsCommand; + } + + + /** + * @param warpsCommand the warpsCommand to set + */ + public void setWarpsCommand(String warpsCommand) { + this.warpsCommand = warpsCommand; + } + + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index db7d030..a723f46 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -34,4 +34,10 @@ lore-format: &f # # Allow random teleport - adds a button to the warp panel that goes to a random warp sign random-allowed: true - +# +# Allow use in other worlds. Players must have the welcomewarpsigns.warp permission. +allow-in-other-worlds: false +# +# Warp and warps commands. You can change them if they clash with other addons or plugins. +warp-command: warp +warps-command: warps diff --git a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java index 62b3f7f..bd1e4d5 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.when; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.never; import java.util.HashMap; import java.util.Map; @@ -79,6 +80,8 @@ public class WarpSignsListenerTest { private Settings settings; @Mock private IslandsManager im; + @Mock + private IslandWorldManager iwm; @Before public void setUp() throws Exception { @@ -155,9 +158,10 @@ public class WarpSignsListenerTest { // Sufficient level when(addon.getLevel(any(), any())).thenReturn(100L); - IslandWorldManager iwm = mock(IslandWorldManager.class); + // IWM when(plugin.getIWM()).thenReturn(iwm); when(iwm.getAddon(any())).thenReturn(Optional.empty()); + when(iwm.inWorld(any(World.class))).thenReturn(true); // Util PowerMockito.mockStatic(Util.class); @@ -190,7 +194,7 @@ public class WarpSignsListenerTest { } @Test - public void testOnSignBreakWrongWorld() { + public void testOnSignNotGameWorld() { WarpSignsListener wsl = new WarpSignsListener(addon); BlockBreakEvent e = new BlockBreakEvent(block, player); when(addon.inRegisteredWorld(any())).thenReturn(false); @@ -283,7 +287,7 @@ public class WarpSignsListenerTest { * Sign create */ @Test - public void testOnCreateWrongWorld() { + public void testOnCreateWrongWorldGameWorld() { when(player.hasPermission(anyString())).thenReturn(true); WarpSignsListener wsl = new WarpSignsListener(addon); SignChangeEvent e = new SignChangeEvent(block, player, lines); @@ -292,6 +296,43 @@ public class WarpSignsListenerTest { verify(addon).inRegisteredWorld(Mockito.eq(world)); } + @Test + public void testOnCreateNotGameWorldAllowed() { + when(settings.isAllowInOtherWorlds()).thenReturn(true); + when(iwm.inWorld(any(World.class))).thenReturn(false); + when(player.hasPermission(anyString())).thenReturn(true); + WarpSignsListener wsl = new WarpSignsListener(addon); + SignChangeEvent e = new SignChangeEvent(block, player, lines); + when(addon.inRegisteredWorld(any())).thenReturn(false); + wsl.onSignWarpCreate(e); + verify(player).sendMessage("warps.success"); + assertEquals(ChatColor.GREEN + "[WELCOME]", e.getLine(0)); + } + + @Test + public void testOnCreateNotGameWorldNotAllowed() { + when(settings.isAllowInOtherWorlds()).thenReturn(false); + when(iwm.inWorld(any(World.class))).thenReturn(false); + when(player.hasPermission(anyString())).thenReturn(true); + WarpSignsListener wsl = new WarpSignsListener(addon); + SignChangeEvent e = new SignChangeEvent(block, player, lines); + when(addon.inRegisteredWorld(any())).thenReturn(false); + wsl.onSignWarpCreate(e); + verify(player, never()).sendMessage("warps.success"); + } + + @Test + public void testOnCreateNotGameWorldNoPerm() { + when(settings.isAllowInOtherWorlds()).thenReturn(true); + when(iwm.inWorld(any(World.class))).thenReturn(false); + when(player.hasPermission(anyString())).thenReturn(false); + WarpSignsListener wsl = new WarpSignsListener(addon); + SignChangeEvent e = new SignChangeEvent(block, player, lines); + when(addon.inRegisteredWorld(any())).thenReturn(false); + wsl.onSignWarpCreate(e); + verify(player).sendMessage("warps.error.no-permission"); + } + @Test public void testOnCreateWrongText() { when(player.hasPermission(anyString())).thenReturn(true); From 007f071234a34e215ce76bd53b536f32de38c6a5 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 10:18:13 -0700 Subject: [PATCH 11/17] Enabling sonarcloud --- .travis.yml | 22 ++++++++++++++++++++++ pom.xml | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b76061a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +language: java +sudo: false +addons: + sonarcloud: + organization: "bentobox-world" + token: + secure: $SONAR_TOKEN +jdk: + - openjdk8 + - openjdk11 + +matrix: + allow_failures: + - jdk: openjdk11 + +script: + mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=BentoBoxWorld_Warps + +cache: + directories: + - '$HOME/.m2/repository' + - '$HOME/.sonar/cache' diff --git a/pom.xml b/pom.xml index 63cd4af..b730df8 100644 --- a/pom.xml +++ b/pom.xml @@ -113,14 +113,14 @@ sonar https://sonarcloud.io - tastybento-github + bentobox-world org.sonarsource.scanner.maven sonar-maven-plugin - 3.4.1.1168 + 3.6.0.1398 verify From 85334079daed4b3c5d2b6ff7ea2da9b2fa21a87b Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 14:12:44 -0700 Subject: [PATCH 12/17] Fixed code smells --- pom.xml | 155 +++++++++--------- src/main/java/world/bentobox/warps/Warp.java | 14 +- .../bentobox/warps/WarpPanelManager.java | 27 ++- .../bentobox/warps/WarpSignsListener.java | 89 ++++++---- .../bentobox/warps/WarpSignsManager.java | 38 +++-- .../bentobox/warps/commands/WarpCommand.java | 2 +- .../bentobox/warps/event/WarpCreateEvent.java | 58 +++---- .../warps/event/WarpInitiateEvent.java | 61 ++++--- .../bentobox/warps/objects/WarpsData.java | 12 +- .../bentobox/warps/WarpSignsListenerTest.java | 10 -- 10 files changed, 241 insertions(+), 225 deletions(-) diff --git a/pom.xml b/pom.xml index b730df8..da4c79c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,20 +1,20 @@ - 4.0.0 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - world.bentobox - warps + world.bentobox + warps ${revision} - WelcomeWarpSigns - WelcomeWarpSigns is an add-on for BentoBox, an expandable Minecraft Bukkit plugin for island-type games like ASkyBlock or AcidIsland. - https://github.com/BentoBoxWorld/addon-welcomewarpsigns - 2018 + WelcomeWarpSigns + WelcomeWarpSigns is an add-on for BentoBox, an expandable Minecraft Bukkit plugin for island-type games like ASkyBlock or AcidIsland. + https://github.com/BentoBoxWorld/addon-welcomewarpsigns + 2018 - + tastybento tastybento@bentobox.world -8 @@ -24,34 +24,34 @@ - - scm:git:https://github.com/BentoBoxWorld/addon-welcomewarpsigns.git - scm:git:git@github.com:BentoBoxWorld/addon-welcomewarpsigns.git - https://github.com/BentoBoxWorld/addon-welcomewarpsigns - + + scm:git:https://github.com/BentoBoxWorld/addon-welcomewarpsigns.git + scm:git:git@github.com:BentoBoxWorld/addon-welcomewarpsigns.git + https://github.com/BentoBoxWorld/addon-welcomewarpsigns + - - jenkins - http://ci.codemc.org/job/BentoBoxWorld/job/addon-welcomewarpsigns - + + jenkins + http://ci.codemc.org/job/BentoBoxWorld/job/addon-welcomewarpsigns + - - GitHub - https://github.com/BentoBoxWorld/addon-welcomewarpsigns/issues - + + GitHub + https://github.com/BentoBoxWorld/addon-welcomewarpsigns/issues + - - - codemc-snapshots - https://repo.codemc.org/repository/maven-snapshots - - - codemc-releases - https://repo.codemc.org/repository/maven-releases - - + + + codemc-snapshots + https://repo.codemc.org/repository/maven-snapshots + + + codemc-releases + https://repo.codemc.org/repository/maven-releases + + - + UTF-8 UTF-8 1.8 @@ -67,7 +67,7 @@ -LOCAL 1.8.0 - + @@ -135,22 +135,22 @@ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots - - - codemc - https://repo.codemc.org/repository/maven-snapshots/ - - - codemc-public - https://repo.codemc.org/repository/maven-public/ - - + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots + + + codemc + https://repo.codemc.org/repository/maven-snapshots/ + + + codemc-public + https://repo.codemc.org/repository/maven-public/ + + - + org.spigotmc @@ -183,15 +183,24 @@ ${bentobox.version} provided - - world.bentobox - level - ${level.version} - provided - - + + world.bentobox + level + ${level.version} + provided + + + + + org.eclipse.jdt + org.eclipse.jdt.annotation + 2.2.200 + + - + @@ -202,18 +211,18 @@ be the empty string. --> ${project.name}-${revision}${build.number} - clean package - - - src/main/resources - true - - - src/main/resources/locales - ./locales - false - - + clean package + + + src/main/resources + true + + + src/main/resources/locales + ./locales + false + + org.apache.maven.plugins @@ -300,8 +309,8 @@ true - + **/*Names* @@ -321,5 +330,5 @@ - + \ No newline at end of file diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index e38f438..18a2072 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -115,16 +115,14 @@ public class Warp extends Addon { // Register commands this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> { - if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName())) + if (!this.settings.getDisabledGameModes().contains(gameModeAddon.getDescription().getName()) + && gameModeAddon.getPlayerCommand().isPresent()) { - if (gameModeAddon.getPlayerCommand().isPresent()) - { - this.registeredWorlds.add(gameModeAddon.getOverWorld()); + this.registeredWorlds.add(gameModeAddon.getOverWorld()); - new WarpCommand(this, gameModeAddon.getPlayerCommand().get()); - new WarpsCommand(this, gameModeAddon.getPlayerCommand().get()); - this.hooked = true; - } + new WarpCommand(this, gameModeAddon.getPlayerCommand().get()); + new WarpsCommand(this, gameModeAddon.getPlayerCommand().get()); + this.hooked = true; } }); diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java index 1a7f6a9..c6d0e67 100644 --- a/src/main/java/world/bentobox/warps/WarpPanelManager.java +++ b/src/main/java/world/bentobox/warps/WarpPanelManager.java @@ -11,6 +11,7 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.inventory.ItemStack; +import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; @@ -33,12 +34,7 @@ public class WarpPanelManager { PanelItemBuilder pib = new PanelItemBuilder() .name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner)) .description(getSign(world, warpOwner)) - .clickHandler((panel, clicker, click, slot) -> { { - clicker.closeInventory(); - addon.getWarpSignsManager().warpPlayer(world, clicker, warpOwner); - return true; - } - }); + .clickHandler((panel, clicker, click, slot) -> hander(panel, world, clicker, warpOwner)); Material icon = getSignIcon(world, warpOwner); if (icon.equals(Material.PLAYER_HEAD)) { return pib.icon(addon.getPlayers().getName(warpOwner)).build(); @@ -47,16 +43,17 @@ public class WarpPanelManager { } } + private boolean hander(Panel panel, World world, User clicker, UUID warpOwner) { + clicker.closeInventory(); + addon.getWarpSignsManager().warpPlayer(world, clicker, warpOwner); + return true; + } + private PanelItem getRandomButton(World world, User user, UUID warpOwner) { - ///give @p minecraft:player_head{display:{Name:"{\"text\":\"Question Mark\"}"},SkullOwner:"MHF_Question"} 1 + ///give @p minecraft:player_head{display:{Name:"{\"text\":\"Question Mark\"}"},SkullOwner:"MHF_Question"} 1 return new PanelItemBuilder() .name(addon.getSettings().getNameFormat() + user.getTranslation("warps.random")) - .clickHandler((panel, clicker, click, slot) -> { { - clicker.closeInventory(); - addon.getWarpSignsManager().warpPlayer(world, clicker, warpOwner); - return true; - } - }) + .clickHandler((panel, clicker, click, slot) -> hander(panel, world, clicker, warpOwner)) .icon(Material.END_CRYSTAL).build(); } @@ -99,7 +96,7 @@ public class WarpPanelManager { List warps = new ArrayList<>(addon.getWarpSignsManager().getSortedWarps(world)); UUID randomWarp = null; // Add random UUID - if (!warps.isEmpty() && addon.getSettings().isRandomAllowed()) { + if (!warps.isEmpty() && addon.getSettings().isRandomAllowed()) { randomWarp = warps.get(new Random().nextInt(warps.size())); warps.add(0, randomWarp); } @@ -110,7 +107,7 @@ public class WarpPanelManager { } PanelBuilder panelBuilder = new PanelBuilder() .user(user) - .name(user.getTranslation("warps.title") + " " + String.valueOf(index + 1)); + .name(user.getTranslation("warps.title") + " " + (index + 1)); int i = index * PANEL_MAX_SIZE; for (; i < (index * PANEL_MAX_SIZE + PANEL_MAX_SIZE) && i < warps.size(); i++) { diff --git a/src/main/java/world/bentobox/warps/WarpSignsListener.java b/src/main/java/world/bentobox/warps/WarpSignsListener.java index 74e7493..364fe6f 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/WarpSignsListener.java @@ -6,6 +6,7 @@ import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.event.EventHandler; @@ -46,20 +47,17 @@ public class WarpSignsListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onSignBreak(BlockBreakEvent e) { Block b = e.getBlock(); + boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld()); // Signs only // FIXME: When we drop support for 1.13, switch to Tag.SIGNS if (!e.getBlock().getType().name().contains("SIGN")) { return; } - if ((addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.inRegisteredWorld(b.getWorld())) - || (!addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.getSettings().isAllowInOtherWorlds()) ) { + if ((inWorld && !addon.inRegisteredWorld(b.getWorld())) || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) { return; } User user = User.getInstance(e.getPlayer()); Sign s = (Sign) b.getState(); - if (s == null) { - return; - } if (s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { // Do a quick check to see if this sign location is in // the list of warp signs @@ -67,8 +65,9 @@ public class WarpSignsListener implements Listener { if (list.containsValue(s.getLocation())) { // Welcome sign detected - check to see if it is // this player's sign + String reqPerm = inWorld ? addon.getPermPrefix(e.getBlock().getWorld()) + "mod.removesign" : "welcomewarpsigns.mod.removesign"; if ((list.containsKey(user.getUniqueId()) && list.get(user.getUniqueId()).equals(s.getLocation())) - || user.isOp() || user.hasPermission(addon.getPermPrefix(e.getBlock().getWorld()) + "mod.removesign")) { + || user.isOp() || user.hasPermission(reqPerm)) { addon.getWarpSignsManager().removeWarp(s.getLocation()); Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(addon, s.getLocation(), user.getUniqueId())); } else { @@ -88,8 +87,8 @@ public class WarpSignsListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onSignWarpCreate(SignChangeEvent e) { Block b = e.getBlock(); - if ((addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.inRegisteredWorld(b.getWorld())) - || (!addon.getPlugin().getIWM().inWorld(b.getWorld()) && !addon.getSettings().isAllowInOtherWorlds()) ) { + boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld()); + if ((inWorld && !addon.inRegisteredWorld(b.getWorld())) || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) { return; } String title = e.getLine(0); @@ -97,28 +96,12 @@ public class WarpSignsListener implements Listener { // Check if someone is changing their own sign if (title.equalsIgnoreCase(addon.getSettings().getWelcomeLine())) { // Welcome sign detected - check permissions - if (!(user.hasPermission(addon.getPermPrefix(b.getWorld()) + "island.addwarp"))) { - user.sendMessage("warps.error.no-permission"); - user.sendMessage("general.errors.no-permission", "[permission]", addon.getPermPrefix(b.getWorld()) + "island.addwarp"); + if (noPerms(user, b.getWorld(), inWorld)) { return; } - if (addon.getPlugin().getIWM().inWorld(b.getWorld())) { - // Get level if level addon is available - Long level = addon.getLevel(Util.getWorld(b.getWorld()), user.getUniqueId()); - if (level != null && level < addon.getSettings().getWarpLevelRestriction()) { - user.sendMessage("warps.error.not-enough-level"); - user.sendMessage("warps.error.your-level-is", - "[level]", String.valueOf(level), - "[required]", String.valueOf(addon.getSettings().getWarpLevelRestriction())); - return; - } - - // Check that the player is on their island - if (!(plugin.getIslands().userIsOnIsland(b.getWorld(), user))) { - user.sendMessage("warps.error.not-on-island"); - e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); - return; - } + if (inWorld && noLevelOrIsland(user, b.getWorld())) { + e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); + return; } // Check if the player already has a sign final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId()); @@ -135,14 +118,12 @@ public class WarpSignsListener implements Listener { if (oldSignBlock.getType().name().contains("SIGN")) { // The block is still a sign Sign oldSign = (Sign) oldSignBlock.getState(); - if (oldSign != null) { - if (oldSign.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { - oldSign.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); - oldSign.update(true, false); - user.sendMessage("warps.deactivate"); - addon.getWarpSignsManager().removeWarp(oldSignBlock.getWorld(), user.getUniqueId()); - Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(addon, oldSign.getLocation(), user.getUniqueId())); - } + if (oldSign.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { + oldSign.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); + oldSign.update(true, false); + user.sendMessage("warps.deactivate"); + addon.getWarpSignsManager().removeWarp(oldSignBlock.getWorld(), user.getUniqueId()); + Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(addon, oldSign.getLocation(), user.getUniqueId())); } } // Set up the new warp sign @@ -152,6 +133,42 @@ public class WarpSignsListener implements Listener { } + private boolean noLevelOrIsland(User user, World world) { + // Get level if level addon is available + Long level = addon.getLevel(Util.getWorld(world), user.getUniqueId()); + if (level != null && level < addon.getSettings().getWarpLevelRestriction()) { + user.sendMessage("warps.error.not-enough-level"); + user.sendMessage("warps.error.your-level-is", + "[level]", String.valueOf(level), + "[required]", String.valueOf(addon.getSettings().getWarpLevelRestriction())); + return true; + } + + // Check that the player is on their island + if (!(plugin.getIslands().userIsOnIsland(world, user))) { + user.sendMessage("warps.error.not-on-island"); + return true; + } + return false; + } + + /** + * Check if player has permission to execute command + * @param user - user + * @param world - world that the warp is in + * @param inWorld - true if warp is in a game world + * @return true if player does not have the required perms, false otherwise + */ + private boolean noPerms(User user, World world, boolean inWorld) { + String permReq = inWorld ? addon.getPermPrefix(world) + "island.addwarp" : "welcomewarpsigns.addwarp"; + if (!(user.hasPermission(permReq))) { + user.sendMessage("warps.error.no-permission"); + user.sendMessage("general.errors.no-permission", "[permission]", permReq); + return true; + } + return false; + } + private void addSign(SignChangeEvent e, User user, Block b) { if (addon.getWarpSignsManager().addWarp(user.getUniqueId(), b.getLocation())) { user.sendMessage("warps.success"); diff --git a/src/main/java/world/bentobox/warps/WarpSignsManager.java b/src/main/java/world/bentobox/warps/WarpSignsManager.java index 9b4bc72..da6040c 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/WarpSignsManager.java @@ -25,6 +25,8 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.permissions.PermissionAttachmentInfo; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; @@ -59,7 +61,8 @@ public class WarpSignsManager { * @param world - world * @return map of warps */ - public Map getWarpMap(World world) { + @NonNull + public Map getWarpMap(@Nullable World world) { return worldsWarpList.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()); } @@ -108,6 +111,7 @@ public class WarpSignsManager { * - the warp requested * @return Location of warp or null */ + @Nullable public Location getWarp(World world, UUID playerUUID) { return getWarpMap(world).get(playerUUID); } @@ -117,6 +121,7 @@ public class WarpSignsManager { * @param location to search * @return Name of warp owner or empty string if there is none */ + @NonNull public String getWarpOwner(Location location) { return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().equals(location)) .findFirst().map(en -> plugin.getPlayers().getName(en.getKey())).orElse(""); @@ -126,11 +131,12 @@ public class WarpSignsManager { * Get sorted list of warps with most recent players listed first * @return UUID list */ - public List getSortedWarps(World world) { + @NonNull + public List getSortedWarps(@NonNull World world) { // Remove any null locations - this can happen if an admin changes the name of the world and signs point to old locations getWarpMap(world).values().removeIf(Objects::isNull); // Bigger value of time means a more recent login - TreeMap map = new TreeMap(); + TreeMap map = new TreeMap<>(); getWarpMap(world).entrySet().forEach(en -> { UUID uuid = en.getKey(); // If never played, will be zero @@ -160,7 +166,8 @@ public class WarpSignsManager { * * @return UUID set of warps */ - public Set listWarps(World world) { + @NonNull + public Set listWarps(@NonNull World world) { // Remove any null locations getWarpMap(world).values().removeIf(Objects::isNull); return getWarpMap(world).entrySet().stream().filter(e -> Util.sameWorld(world, e.getValue().getWorld())).map(Map.Entry::getKey).collect(Collectors.toSet()); @@ -194,11 +201,9 @@ public class WarpSignsManager { Block b = loc.getBlock(); if (b.getType().name().contains("SIGN")) { Sign s = (Sign) b.getState(); - if (s != null) { - if (s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { - s.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); - s.update(true, false); - } + if (s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { + s.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); + s.update(true, false); } } } @@ -257,7 +262,8 @@ public class WarpSignsManager { * @param uuid - player's uuid * @return Sign's content and type */ - public SignCache getSignInfo(World world, UUID uuid) { + @NonNull + public SignCache getSignInfo(@NonNull World world, @NonNull UUID uuid) { List result = new ArrayList<>(); //get the sign info Location signLocation = getWarp(world, uuid); @@ -309,7 +315,7 @@ public class WarpSignsManager { * @param directionFacing - direction that sign is facing * @param pvp - true if this location allowed PVP */ - private void warpPlayer(User user, Location inFront, UUID signOwner, BlockFace directionFacing, boolean pvp) { + private void warpPlayer(@NonNull User user, @NonNull Location inFront, @NonNull UUID signOwner, @NonNull BlockFace directionFacing, boolean pvp) { // convert blockface to angle float yaw = blockFaceToFloat(directionFacing); final Location actualWarp = new Location(inFront.getWorld(), inFront.getBlockX() + 0.5D, inFront.getBlockY(), @@ -334,7 +340,7 @@ public class WarpSignsManager { * @param face * @return degrees */ - private float blockFaceToFloat(BlockFace face) { + private float blockFaceToFloat(@NonNull BlockFace face) { switch (face) { case EAST: return 90F; @@ -380,7 +386,7 @@ public class WarpSignsManager { * @param user - user who is warping * @param owner - owner of the warp */ - public void warpPlayer(World world, User user, UUID owner) { + public void warpPlayer(@NonNull World world, @NonNull User user, @NonNull UUID owner) { final Location warpSpot = getWarp(world, owner); // Check if the warp spot is safe if (warpSpot == null) { @@ -447,7 +453,6 @@ public class WarpSignsManager { } if (!(plugin.getIslands().isSafeLocation(warpSpot))) { user.sendMessage("warps.error.not-safe"); - return; } else { final Location actualWarp = new Location(warpSpot.getWorld(), warpSpot.getBlockX() + 0.5D, warpSpot.getBlockY(), warpSpot.getBlockZ() + 0.5D); @@ -458,7 +463,6 @@ public class WarpSignsManager { user.getWorld().playSound(user.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 1F, 1F); } user.teleport(actualWarp); - return; } } @@ -467,7 +471,7 @@ public class WarpSignsManager { * @param playerUUID - player's UUID * @return true if they have warp */ - public boolean hasWarp(World world, UUID playerUUID) { + public boolean hasWarp(@NonNull World world, @NonNull UUID playerUUID) { return getWarpMap(world).containsKey(playerUUID); } @@ -485,7 +489,7 @@ public class WarpSignsManager { * @param defaultValue Default value that will be returned if permission not found. * @return String value that follows permissionPrefix. */ - private String getPermissionValue(User user, String permissionPrefix, String defaultValue) + private String getPermissionValue(@NonNull User user, @NonNull String permissionPrefix, @NonNull String defaultValue) { if (user.isPlayer()) { diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index ae9dc9c..f5137fc 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -54,7 +54,7 @@ public class WarpCommand extends CompositeCommand { return true; } else { // Check if this is part of a name - UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).toLowerCase().equals(args.get(0).toLowerCase()) + UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).equalsIgnoreCase(args.get(0)) || getPlayers().getName(u).toLowerCase().startsWith(args.get(0).toLowerCase())).findFirst().orElse(null); if (foundWarp == null) { user.sendMessage("warps.error.does-not-exist"); diff --git a/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java b/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java index 0c87f21..cdf7b81 100644 --- a/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java +++ b/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java @@ -11,39 +11,39 @@ import world.bentobox.warps.Warp; /** * This event is fired when a Warp is created * A Listener to this event can use it only to get informations. e.g: broadcast something - * + * * @author Poslovitch * */ public class WarpCreateEvent extends Event{ - private static final HandlerList handlers = new HandlerList(); - - private Location warpLoc; - private UUID creator; - - /** - * @param plugin - BSkyBlock plugin objects - * @param warpLoc - * @param creator - */ - public WarpCreateEvent(Warp plugin, Location warpLoc, UUID creator){ - this.warpLoc = warpLoc; - this.creator = creator; - } - - /** - * Get the location of the created Warp - * @return created warp's location - */ - public Location getWarpLocation(){return this.warpLoc;} - - /** - * Get who has created the warp - * @return the warp's creator - */ - public UUID getCreator(){return this.creator;} - - @Override + private static final HandlerList handlers = new HandlerList(); + + private Location warpLoc; + private UUID creator; + + /** + * @param plugin - BSkyBlock plugin objects + * @param warpLoc + * @param creator + */ + public WarpCreateEvent(Warp plugin, Location warpLoc, UUID creator){ + this.warpLoc = warpLoc; + this.creator = creator; + } + + /** + * Get the location of the created Warp + * @return created warp's location + */ + public Location getWarpLocation(){return this.warpLoc;} + + /** + * Get who has created the warp + * @return the warp's creator + */ + public UUID getCreator(){return this.creator;} + + @Override public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/world/bentobox/warps/event/WarpInitiateEvent.java b/src/main/java/world/bentobox/warps/event/WarpInitiateEvent.java index 0d4725d..1e50a3b 100644 --- a/src/main/java/world/bentobox/warps/event/WarpInitiateEvent.java +++ b/src/main/java/world/bentobox/warps/event/WarpInitiateEvent.java @@ -10,34 +10,34 @@ import org.bukkit.event.HandlerList; import world.bentobox.warps.Warp; /** - * This event is fired when a player tries to do a warp + * This event is fired when a player tries to do a warp * A Listener to this event can use it to get informations. e.g: broadcast something - * + * * @author tastybento * */ public class WarpInitiateEvent extends Event implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private boolean cancelled; - private Location warpLoc; - private final UUID player; - - /** - * @param plugin - BSkyBlock plugin objects - * @param warpLoc - where the player is warping to - * @param player - the UUID of the player - */ - public WarpInitiateEvent(Warp plugin, Location warpLoc, UUID player){ - this.warpLoc = warpLoc; - this.player = player; - } - - /** - * Get the location of the Warp - * @return created warp's location - */ - public Location getWarpLoc(){return this.warpLoc;} - + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private Location warpLoc; + private final UUID player; + + /** + * @param plugin - BSkyBlock plugin objects + * @param warpLoc - where the player is warping to + * @param player - the UUID of the player + */ + public WarpInitiateEvent(Warp plugin, Location warpLoc, UUID player){ + this.warpLoc = warpLoc; + this.player = player; + } + + /** + * Get the location of the Warp + * @return created warp's location + */ + public Location getWarpLoc(){return this.warpLoc;} + /** * Set a different location to where the player will go * @param warpLoc @@ -47,12 +47,12 @@ public class WarpInitiateEvent extends Event implements Cancellable { } /** - * Get who is warping - * @return the warping player's uuid - */ - public UUID getPlayer(){return this.player;} - - @Override + * Get who is warping + * @return the warping player's uuid + */ + public UUID getPlayer(){return this.player;} + + @Override public HandlerList getHandlers() { return handlers; } @@ -63,13 +63,12 @@ public class WarpInitiateEvent extends Event implements Cancellable { @Override public boolean isCancelled() { - // TODO Auto-generated method stub return cancelled; } @Override public void setCancelled(boolean cancelled) { this.cancelled = cancelled; - + } } diff --git a/src/main/java/world/bentobox/warps/objects/WarpsData.java b/src/main/java/world/bentobox/warps/objects/WarpsData.java index 9fc6757..ad4a1f3 100644 --- a/src/main/java/world/bentobox/warps/objects/WarpsData.java +++ b/src/main/java/world/bentobox/warps/objects/WarpsData.java @@ -12,13 +12,15 @@ import com.google.gson.annotations.Expose; import world.bentobox.bentobox.database.objects.DataObject; public class WarpsData implements DataObject { - + @Expose private String uniqueId = "warps"; @Expose private Map warpSigns = new HashMap<>(); - - public WarpsData() {} + + public WarpsData() { + // Required by YAML database + } @Override public String getUniqueId() { @@ -31,8 +33,8 @@ public class WarpsData implements DataObject { } public Map getWarpSigns() { - if (warpSigns == null) - return new HashMap<>(); + if (warpSigns == null) + return new HashMap<>(); return warpSigns; } diff --git a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java index bd1e4d5..da5ecea 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java @@ -203,16 +203,6 @@ public class WarpSignsListenerTest { verify(addon).inRegisteredWorld(Mockito.eq(world)); } - @Test - public void testOnSignBreakNullState() { - WarpSignsListener wsl = new WarpSignsListener(addon); - BlockBreakEvent e = new BlockBreakEvent(block, player); - when(block.getState()).thenReturn(null); - wsl.onSignBreak(e); - assertFalse(e.isCancelled()); - verify(block).getState(); - } - @Test public void testOnSignNotWelcomeSign() { WarpSignsListener wsl = new WarpSignsListener(addon); From 6d788b6f66c6c8f7a2d258177c692d4da7ca05cd Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 14:22:32 -0700 Subject: [PATCH 13/17] Fixes potential null bugs --- src/main/java/world/bentobox/warps/Warp.java | 13 +++++++++---- .../world/bentobox/warps/WarpSignsListener.java | 4 ++-- .../world/bentobox/warps/commands/WarpCommand.java | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 18a2072..482fe79 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -18,7 +18,7 @@ import world.bentobox.warps.commands.WarpsCommand; import world.bentobox.warps.config.Settings; /** - * Addin to BSkyBlock that enables welcome warp signs + * Addin to BentoBox that enables welcome warp signs * @author tastybento * */ @@ -32,6 +32,11 @@ public class Warp extends Addon { */ private static final String LEVEL_ADDON_NAME = "Level"; + /** + * Permission prefix for non-game world operation + */ + public static final String WELCOME_WARP_SIGNS = "welcomewarpsigns"; + /** * Warp panel Manager */ @@ -220,8 +225,8 @@ public class Warp extends Addon { // Parse keys if (metaData.containsKey("world")) { world = Bukkit.getWorld((String)metaData.get("world")); - if (world == null) return null; } + if (world == null) return null; if (metaData.containsKey("uuid")) { try { uuid = UUID.fromString((String)metaData.get("uuid")); @@ -234,11 +239,11 @@ public class Warp extends Addon { case "getSortedWarps": return getWarpSignsManager().getSortedWarps(world); case "getWarp": - return getWarpSignsManager().getWarp(world, uuid); + return uuid == null ? null : getWarpSignsManager().getWarp(world, uuid); case "getWarpMap": return getWarpSignsManager().getWarpMap(world); case "hasWarp": - return getWarpSignsManager().hasWarp(world, uuid); + return uuid == null ? null : getWarpSignsManager().hasWarp(world, uuid); case "listWarps": return getWarpSignsManager().listWarps(world); default: diff --git a/src/main/java/world/bentobox/warps/WarpSignsListener.java b/src/main/java/world/bentobox/warps/WarpSignsListener.java index 364fe6f..d564d1c 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/WarpSignsListener.java @@ -65,7 +65,7 @@ public class WarpSignsListener implements Listener { if (list.containsValue(s.getLocation())) { // Welcome sign detected - check to see if it is // this player's sign - String reqPerm = inWorld ? addon.getPermPrefix(e.getBlock().getWorld()) + "mod.removesign" : "welcomewarpsigns.mod.removesign"; + String reqPerm = inWorld ? addon.getPermPrefix(e.getBlock().getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign"; if ((list.containsKey(user.getUniqueId()) && list.get(user.getUniqueId()).equals(s.getLocation())) || user.isOp() || user.hasPermission(reqPerm)) { addon.getWarpSignsManager().removeWarp(s.getLocation()); @@ -160,7 +160,7 @@ public class WarpSignsListener implements Listener { * @return true if player does not have the required perms, false otherwise */ private boolean noPerms(User user, World world, boolean inWorld) { - String permReq = inWorld ? addon.getPermPrefix(world) + "island.addwarp" : "welcomewarpsigns.addwarp"; + String permReq = inWorld ? addon.getPermPrefix(world) + "island.addwarp" : Warp.WELCOME_WARP_SIGNS + ".addwarp"; if (!(user.hasPermission(permReq))) { user.sendMessage("warps.error.no-permission"); user.sendMessage("general.errors.no-permission", "[permission]", permReq); diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index f5137fc..a4945ce 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -31,7 +31,7 @@ public class WarpCommand extends CompositeCommand { public WarpCommand(Warp addon) { super(addon.getSettings().getWarpCommand()); this.addon = addon; - perm = "welcomewarpsigns"; + perm = Warp.WELCOME_WARP_SIGNS; } @Override From 55558711cc76297468b6cd0d689f95d31417c418 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 14:49:26 -0700 Subject: [PATCH 14/17] Code smell - simplified listener --- .../bentobox/warps/WarpPanelManager.java | 7 ++- .../bentobox/warps/WarpSignsListener.java | 48 ++++++++++--------- .../bentobox/warps/WarpSignsListenerTest.java | 1 + 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java index c6d0e67..236551a 100644 --- a/src/main/java/world/bentobox/warps/WarpPanelManager.java +++ b/src/main/java/world/bentobox/warps/WarpPanelManager.java @@ -11,7 +11,6 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.inventory.ItemStack; -import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; @@ -34,7 +33,7 @@ public class WarpPanelManager { PanelItemBuilder pib = new PanelItemBuilder() .name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner)) .description(getSign(world, warpOwner)) - .clickHandler((panel, clicker, click, slot) -> hander(panel, world, clicker, warpOwner)); + .clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner)); Material icon = getSignIcon(world, warpOwner); if (icon.equals(Material.PLAYER_HEAD)) { return pib.icon(addon.getPlayers().getName(warpOwner)).build(); @@ -43,7 +42,7 @@ public class WarpPanelManager { } } - private boolean hander(Panel panel, World world, User clicker, UUID warpOwner) { + private boolean hander(World world, User clicker, UUID warpOwner) { clicker.closeInventory(); addon.getWarpSignsManager().warpPlayer(world, clicker, warpOwner); return true; @@ -53,7 +52,7 @@ public class WarpPanelManager { ///give @p minecraft:player_head{display:{Name:"{\"text\":\"Question Mark\"}"},SkullOwner:"MHF_Question"} 1 return new PanelItemBuilder() .name(addon.getSettings().getNameFormat() + user.getTranslation("warps.random")) - .clickHandler((panel, clicker, click, slot) -> hander(panel, world, clicker, warpOwner)) + .clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner)) .icon(Material.END_CRYSTAL).build(); } diff --git a/src/main/java/world/bentobox/warps/WarpSignsListener.java b/src/main/java/world/bentobox/warps/WarpSignsListener.java index d564d1c..2ed72a3 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/WarpSignsListener.java @@ -9,6 +9,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -50,35 +51,38 @@ public class WarpSignsListener implements Listener { boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld()); // Signs only // FIXME: When we drop support for 1.13, switch to Tag.SIGNS - if (!e.getBlock().getType().name().contains("SIGN")) { - return; - } - if ((inWorld && !addon.inRegisteredWorld(b.getWorld())) || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) { + if (!e.getBlock().getType().name().contains("SIGN") + || (inWorld && !addon.inRegisteredWorld(b.getWorld())) + || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) { return; } User user = User.getInstance(e.getPlayer()); - Sign s = (Sign) b.getState(); - if (s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) { - // Do a quick check to see if this sign location is in - // the list of warp signs - Map list = addon.getWarpSignsManager().getWarpMap(b.getWorld()); - if (list.containsValue(s.getLocation())) { - // Welcome sign detected - check to see if it is - // this player's sign - String reqPerm = inWorld ? addon.getPermPrefix(e.getBlock().getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign"; - if ((list.containsKey(user.getUniqueId()) && list.get(user.getUniqueId()).equals(s.getLocation())) - || user.isOp() || user.hasPermission(reqPerm)) { - addon.getWarpSignsManager().removeWarp(s.getLocation()); - Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(addon, s.getLocation(), user.getUniqueId())); - } else { - // Someone else's sign - not allowed - user.sendMessage("warps.error.no-remove"); - e.setCancelled(true); - } + if (isWarpSign(b)) { + if (isPlayersSign(e.getPlayer(), b, inWorld)) { + addon.getWarpSignsManager().removeWarp(b.getLocation()); + Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(addon, b.getLocation(), user.getUniqueId())); + } else { + // Someone else's sign - not allowed + user.sendMessage("warps.error.no-remove"); + e.setCancelled(true); } } } + private boolean isPlayersSign(Player player, Block b, boolean inWorld) { + // Welcome sign detected - check to see if it is this player's sign + Map list = addon.getWarpSignsManager().getWarpMap(b.getWorld()); + String reqPerm = inWorld ? addon.getPermPrefix(b.getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign"; + return ((list.containsKey(player.getUniqueId()) && list.get(player.getUniqueId()).equals(b.getLocation())) + || player.isOp() || player.hasPermission(reqPerm)); + } + + private boolean isWarpSign(Block b) { + Sign s = (Sign) b.getState(); + return s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine()) + && addon.getWarpSignsManager().getWarpMap(b.getWorld()).containsValue(s.getLocation()); + } + /** * Event handler for Sign Changes * diff --git a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java index da5ecea..930e170 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsListenerTest.java @@ -124,6 +124,7 @@ public class WarpSignsListenerTest { Location location = mock(Location.class); when(location.getBlock()).thenReturn(block); when(s.getLocation()).thenReturn(location); + when(block.getLocation()).thenReturn(location); list.put(uuid, location); // Player is in world when(wsm.getWarpMap(Mockito.eq(world))).thenReturn(list); From d7e0b366231c690fb32223e90da9c6073fc34394 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 17:05:12 -0700 Subject: [PATCH 15/17] Added WarpCommand test class --- .../bentobox/warps/commands/WarpCommand.java | 18 +- .../bentobox/warps/commands/WarpsCommand.java | 5 +- .../warps/commands/WarpCommandTest.java | 301 ++++++++++++++++++ 3 files changed, 308 insertions(+), 16 deletions(-) create mode 100644 src/test/java/world/bentobox/warps/commands/WarpCommandTest.java diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index a4945ce..e054c78 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import org.bukkit.World; @@ -21,7 +22,6 @@ import world.bentobox.warps.Warp; public class WarpCommand extends CompositeCommand { private Warp addon; - private String perm = "island"; public WarpCommand(Warp addon, CompositeCommand bsbIslandCmd) { super(bsbIslandCmd, addon.getSettings().getWarpCommand()); @@ -31,12 +31,11 @@ public class WarpCommand extends CompositeCommand { public WarpCommand(Warp addon) { super(addon.getSettings().getWarpCommand()); this.addon = addon; - perm = Warp.WELCOME_WARP_SIGNS; } @Override public void setup() { - this.setPermission(perm + ".warp"); + this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".warp" : "island.warp"); this.setOnlyPlayer(true); this.setParametersHelp("warp.help.parameters"); this.setDescription("warp.help.description"); @@ -44,14 +43,14 @@ public class WarpCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { - World world = getWorld() == null ? user.getWorld() : getWorld(); if (args.size() == 1) { + World world = getWorld() == null ? user.getWorld() : getWorld(); // Warp somewhere command Set warpList = addon.getWarpSignsManager().listWarps(world); if (warpList.isEmpty()) { user.sendMessage("warps.error.no-warps-yet"); user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); - return true; + return false; } else { // Check if this is part of a name UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).equalsIgnoreCase(args.get(0)) @@ -73,14 +72,7 @@ public class WarpCommand extends CompositeCommand { @Override public Optional> tabComplete(User user, String alias, List args) { World world = getWorld() == null ? user.getWorld() : getWorld(); - List options = new ArrayList<>(); - final Set warpList = addon.getWarpSignsManager().listWarps(world); - - for (UUID warp : warpList) { - options.add(addon.getPlugin().getPlayers().getName(warp)); - } - - return Optional.of(options); + return Optional.of(addon.getWarpSignsManager().listWarps(world).stream().map(getPlayers()::getName).collect(Collectors.toList())); } diff --git a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java index dec8412..a733fbb 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java @@ -9,13 +9,13 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; /** + * Handles the warps command * @author tastybento * */ public class WarpsCommand extends CompositeCommand { private Warp addon; - private String perm = "island"; public WarpsCommand(Warp addon, CompositeCommand bsbIslandCmd) { super(bsbIslandCmd, addon.getSettings().getWarpsCommand()); @@ -25,7 +25,6 @@ public class WarpsCommand extends CompositeCommand { public WarpsCommand(Warp addon) { super(addon.getSettings().getWarpsCommand()); this.addon = addon; - perm = "welcomewarpsigns"; } /* (non-Javadoc) @@ -33,7 +32,7 @@ public class WarpsCommand extends CompositeCommand { */ @Override public void setup() { - this.setPermission(perm + ".warp"); + this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".warp" : "island.warp"); this.setOnlyPlayer(true); this.setDescription("warps.help.description"); } diff --git a/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java b/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java new file mode 100644 index 0000000..7aa6e31 --- /dev/null +++ b/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java @@ -0,0 +1,301 @@ +package world.bentobox.warps.commands; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.ItemMeta; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +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.api.addons.GameModeAddon; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.warps.Warp; +import world.bentobox.warps.WarpSignsManager; +import world.bentobox.warps.config.Settings; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BentoBox.class}) +public class WarpCommandTest { + + private static final String WELCOME_LINE = "[Welcome]"; + @Mock + private CompositeCommand ic; + private UUID uuid; + @Mock + private User user; + @Mock + private IslandsManager im; + @Mock + private Island island; + @Mock + private World world; + @Mock + private IslandWorldManager iwm; + @Mock + private GameModeAddon gameModeAddon; + @Mock + private Warp addon; + // Command under test + private WarpCommand wc; + @Mock + private Settings settings; + @Mock + private WarpSignsManager wsm; + @Mock + private PlayersManager pm; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + User.setPlugin(plugin); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + // Addon + when(ic.getAddon()).thenReturn(addon); + when(ic.getPermissionPrefix()).thenReturn("bskyblock."); + when(ic.getLabel()).thenReturn("island"); + when(ic.getTopLabel()).thenReturn("island"); + when(ic.getWorld()).thenReturn(world); + when(ic.getTopLabel()).thenReturn("bsb"); + + // IWM friendly name + when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); + when(iwm.inWorld(any(World.class))).thenReturn(true); + Optional optionalAddon = Optional.of(gameModeAddon); + when(iwm.getAddon(any())).thenReturn(optionalAddon); + when(plugin.getIWM()).thenReturn(iwm); + + // Game Mode Addon + @NonNull + Optional optionalAdmin = Optional.of(ic); + when(gameModeAddon.getAdminCommand()).thenReturn(optionalAdmin); + + // World + when(world.toString()).thenReturn("world"); + + // Player + Player p = mock(Player.class); + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(p); + when(user.getName()).thenReturn("tastybento"); + when(user.getPermissionValue(anyString(), anyInt())).thenReturn(-1); + when(user.isPlayer()).thenReturn(true); + when(user.getWorld()).thenReturn(world); + + // Mock item factory (for itemstacks) + PowerMockito.mockStatic(Bukkit.class); + ItemFactory itemFactory = mock(ItemFactory.class); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + ItemMeta itemMeta = mock(ItemMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); + + // Island + when(plugin.getIslands()).thenReturn(im); + when(im.getIsland(any(), any(User.class))).thenReturn(island); + + // settings + when(addon.getSettings()).thenReturn(settings); + when(settings.getWarpCommand()).thenReturn("warp"); + when(settings.getWelcomeLine()).thenReturn(WELCOME_LINE); + + // Warp Signs Manager + when(addon.getWarpSignsManager()).thenReturn(wsm); + @NonNull + Set set = new HashSet<>(); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + when(wsm.listWarps(eq(world))).thenReturn(set); + + // Players Manager + when(plugin.getPlayers()).thenReturn(pm); + when(addon.getPlayers()).thenReturn(pm); + // Repeat twice because it is asked twice + when(pm.getName(any())).thenReturn("tastybento", "tastybento", "poslovich", "poslovich", "BONNe", "BONNe", "Joe"); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + User.clearUsers(); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#WarpCommand(world.bentobox.warps.Warp, world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testWarpCommandWarpCompositeCommand() { + // Command under test + wc = new WarpCommand(addon, ic); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#WarpCommand(world.bentobox.warps.Warp)}. + */ + @Test + public void testWarpCommandWarp() { + // Command under test + wc = new WarpCommand(addon); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#setup()}. + */ + @Test + public void testSetupWarpCompositeCommand() { + testWarpCommandWarpCompositeCommand(); + assertEquals("bskyblock.island.warp", wc.getPermission()); + assertTrue(wc.isOnlyPlayer()); + assertEquals("warp.help.parameters", wc.getParameters()); + assertEquals("warp.help.description", wc.getDescription()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#setup()}. + */ + @Test + public void testSetupWarp() { + testWarpCommandWarp(); + assertEquals(Warp.WELCOME_WARP_SIGNS + ".warp", wc.getPermission()); + assertTrue(wc.isOnlyPlayer()); + assertEquals("warp.help.parameters", wc.getParameters()); + assertEquals("warp.help.description", wc.getDescription()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNoArgs() { + testWarpCommandWarpCompositeCommand(); + wc.execute(user, "warp", Collections.emptyList()); + verify(user).sendMessage(eq("commands.help.header"), eq(TextVariables.LABEL), eq("BSkyBlock")); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringKnownPlayer() { + testWarpCommandWarpCompositeCommand(); + assertTrue(wc.execute(user, "warp", Collections.singletonList("tastybento"))); + verify(wsm).warpPlayer(eq(world), eq(user), any()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringKnownPlayerWarp() { + testWarpCommandWarp(); + assertTrue(wc.execute(user, "warp", Collections.singletonList("tastybento"))); + verify(wsm).warpPlayer(eq(world), eq(user), any()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringKnownPlayerMixedCase() { + testWarpCommandWarpCompositeCommand(); + assertTrue(wc.execute(user, "warp", Collections.singletonList("tAsTyBEnTo"))); + verify(wsm).warpPlayer(eq(world), eq(user), any()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringKnownPlayerStartOnly() { + testWarpCommandWarpCompositeCommand(); + assertTrue(wc.execute(user, "warp", Collections.singletonList("tAsTy"))); + verify(wsm).warpPlayer(eq(world), eq(user), any()); + } + + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringUnknownPlayer() { + testWarpCommandWarpCompositeCommand(); + assertFalse(wc.execute(user, "warp", Collections.singletonList("LSPVicky"))); + verify(user).sendMessage(eq("warps.error.does-not-exist")); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNoWarpsYet() { + when(wsm.listWarps(eq(world))).thenReturn(Collections.emptySet()); + testWarpCommandWarpCompositeCommand(); + assertFalse(wc.execute(user, "warp", Collections.singletonList("LSPVicky"))); + verify(user).sendMessage(eq("warps.error.no-warps-yet")); + verify(user).sendMessage(eq("warps.warpTip"), eq("[text]"), eq(WELCOME_LINE)); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfString() { + testWarpCommandWarpCompositeCommand(); + List op = wc.tabComplete(user, "warp", Collections.singletonList("tas")).get(); + assertEquals("tastybento", op.get(0)); + assertEquals("tastybento", op.get(1)); + assertEquals("poslovich", op.get(2)); + } + +} From 9a234ef950879cc2645053990b7b71583e055261 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 31 Oct 2019 17:33:34 -0700 Subject: [PATCH 16/17] Added WarpsCommand test class --- .../bentobox/warps/commands/WarpCommand.java | 1 - .../bentobox/warps/commands/WarpsCommand.java | 4 +- .../warps/commands/WarpCommandTest.java | 89 ++------- .../warps/commands/WarpsCommandTest.java | 186 ++++++++++++++++++ 4 files changed, 200 insertions(+), 80 deletions(-) create mode 100644 src/test/java/world/bentobox/warps/commands/WarpsCommandTest.java diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index e054c78..d52358c 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -1,6 +1,5 @@ package world.bentobox.warps.commands; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; diff --git a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java index a733fbb..efbbd72 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java @@ -46,9 +46,9 @@ public class WarpsCommand extends CompositeCommand { if (addon.getWarpSignsManager().listWarps(world).isEmpty()) { user.sendMessage("warps.error.no-warps-yet"); user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); - } else { - addon.getWarpPanelManager().showWarpPanel(world, user,0); + return false; } + addon.getWarpPanelManager().showWarpPanel(world, user, 0); return true; } diff --git a/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java b/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java index 7aa6e31..aa4958a 100644 --- a/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java +++ b/src/test/java/world/bentobox/warps/commands/WarpCommandTest.java @@ -4,8 +4,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -14,35 +12,26 @@ import static org.mockito.Mockito.when; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFactory; -import org.bukkit.inventory.meta.ItemMeta; import org.eclipse.jdt.annotation.NonNull; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -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.api.addons.GameModeAddon; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; -import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; import world.bentobox.bentobox.managers.IslandWorldManager; -import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.warps.Warp; import world.bentobox.warps.WarpSignsManager; @@ -63,16 +52,10 @@ public class WarpCommandTest { @Mock private User user; @Mock - private IslandsManager im; - @Mock - private Island island; - @Mock private World world; @Mock private IslandWorldManager iwm; @Mock - private GameModeAddon gameModeAddon; - @Mock private Warp addon; // Command under test private WarpCommand wc; @@ -91,7 +74,6 @@ public class WarpCommandTest { // Set up plugin BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); - User.setPlugin(plugin); // Command manager CommandsManager cm = mock(CommandsManager.class); @@ -99,49 +81,18 @@ public class WarpCommandTest { // Addon when(ic.getAddon()).thenReturn(addon); when(ic.getPermissionPrefix()).thenReturn("bskyblock."); - when(ic.getLabel()).thenReturn("island"); - when(ic.getTopLabel()).thenReturn("island"); when(ic.getWorld()).thenReturn(world); - when(ic.getTopLabel()).thenReturn("bsb"); // IWM friendly name when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(iwm.inWorld(any(World.class))).thenReturn(true); - Optional optionalAddon = Optional.of(gameModeAddon); - when(iwm.getAddon(any())).thenReturn(optionalAddon); when(plugin.getIWM()).thenReturn(iwm); - // Game Mode Addon - @NonNull - Optional optionalAdmin = Optional.of(ic); - when(gameModeAddon.getAdminCommand()).thenReturn(optionalAdmin); - - // World - when(world.toString()).thenReturn("world"); - // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - when(user.isOp()).thenReturn(false); uuid = UUID.randomUUID(); when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); - when(user.getName()).thenReturn("tastybento"); - when(user.getPermissionValue(anyString(), anyInt())).thenReturn(-1); - when(user.isPlayer()).thenReturn(true); when(user.getWorld()).thenReturn(world); - // Mock item factory (for itemstacks) - PowerMockito.mockStatic(Bukkit.class); - ItemFactory itemFactory = mock(ItemFactory.class); - when(Bukkit.getItemFactory()).thenReturn(itemFactory); - ItemMeta itemMeta = mock(ItemMeta.class); - when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); - - // Island - when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(any(), any(User.class))).thenReturn(island); - // settings when(addon.getSettings()).thenReturn(settings); when(settings.getWarpCommand()).thenReturn("warp"); @@ -163,28 +114,12 @@ public class WarpCommandTest { when(pm.getName(any())).thenReturn("tastybento", "tastybento", "poslovich", "poslovich", "BONNe", "BONNe", "Joe"); } - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - User.clearUsers(); - } - - /** - * Test method for {@link world.bentobox.warps.commands.WarpCommand#WarpCommand(world.bentobox.warps.Warp, world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testWarpCommandWarpCompositeCommand() { + public void warpCommandWarpCompositeCommand() { // Command under test wc = new WarpCommand(addon, ic); } - /** - * Test method for {@link world.bentobox.warps.commands.WarpCommand#WarpCommand(world.bentobox.warps.Warp)}. - */ - @Test - public void testWarpCommandWarp() { + public void warpCommandWarp() { // Command under test wc = new WarpCommand(addon); } @@ -194,7 +129,7 @@ public class WarpCommandTest { */ @Test public void testSetupWarpCompositeCommand() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertEquals("bskyblock.island.warp", wc.getPermission()); assertTrue(wc.isOnlyPlayer()); assertEquals("warp.help.parameters", wc.getParameters()); @@ -206,7 +141,7 @@ public class WarpCommandTest { */ @Test public void testSetupWarp() { - testWarpCommandWarp(); + warpCommandWarp(); assertEquals(Warp.WELCOME_WARP_SIGNS + ".warp", wc.getPermission()); assertTrue(wc.isOnlyPlayer()); assertEquals("warp.help.parameters", wc.getParameters()); @@ -218,7 +153,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringNoArgs() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); wc.execute(user, "warp", Collections.emptyList()); verify(user).sendMessage(eq("commands.help.header"), eq(TextVariables.LABEL), eq("BSkyBlock")); } @@ -228,7 +163,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringKnownPlayer() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertTrue(wc.execute(user, "warp", Collections.singletonList("tastybento"))); verify(wsm).warpPlayer(eq(world), eq(user), any()); } @@ -238,7 +173,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringKnownPlayerWarp() { - testWarpCommandWarp(); + warpCommandWarp(); assertTrue(wc.execute(user, "warp", Collections.singletonList("tastybento"))); verify(wsm).warpPlayer(eq(world), eq(user), any()); } @@ -248,7 +183,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringKnownPlayerMixedCase() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertTrue(wc.execute(user, "warp", Collections.singletonList("tAsTyBEnTo"))); verify(wsm).warpPlayer(eq(world), eq(user), any()); } @@ -258,7 +193,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringKnownPlayerStartOnly() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertTrue(wc.execute(user, "warp", Collections.singletonList("tAsTy"))); verify(wsm).warpPlayer(eq(world), eq(user), any()); } @@ -269,7 +204,7 @@ public class WarpCommandTest { */ @Test public void testExecuteUserStringListOfStringUnknownPlayer() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertFalse(wc.execute(user, "warp", Collections.singletonList("LSPVicky"))); verify(user).sendMessage(eq("warps.error.does-not-exist")); } @@ -280,7 +215,7 @@ public class WarpCommandTest { @Test public void testExecuteUserStringListOfStringNoWarpsYet() { when(wsm.listWarps(eq(world))).thenReturn(Collections.emptySet()); - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); assertFalse(wc.execute(user, "warp", Collections.singletonList("LSPVicky"))); verify(user).sendMessage(eq("warps.error.no-warps-yet")); verify(user).sendMessage(eq("warps.warpTip"), eq("[text]"), eq(WELCOME_LINE)); @@ -291,7 +226,7 @@ public class WarpCommandTest { */ @Test public void testTabCompleteUserStringListOfString() { - testWarpCommandWarpCompositeCommand(); + warpCommandWarpCompositeCommand(); List op = wc.tabComplete(user, "warp", Collections.singletonList("tas")).get(); assertEquals("tastybento", op.get(0)); assertEquals("tastybento", op.get(1)); diff --git a/src/test/java/world/bentobox/warps/commands/WarpsCommandTest.java b/src/test/java/world/bentobox/warps/commands/WarpsCommandTest.java new file mode 100644 index 0000000..1cf8d41 --- /dev/null +++ b/src/test/java/world/bentobox/warps/commands/WarpsCommandTest.java @@ -0,0 +1,186 @@ +package world.bentobox.warps.commands; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +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.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.warps.Warp; +import world.bentobox.warps.WarpPanelManager; +import world.bentobox.warps.WarpSignsManager; +import world.bentobox.warps.config.Settings; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BentoBox.class}) +public class WarpsCommandTest { + + private static final String WELCOME_LINE = "[Welcome]"; + @Mock + private CompositeCommand ic; + @Mock + private User user; + @Mock + private World world; + @Mock + private IslandWorldManager iwm; + @Mock + private Warp addon; + // Command under test + private WarpsCommand wc; + @Mock + private Settings settings; + @Mock + private WarpSignsManager wsm; + @Mock + private PlayersManager pm; + @Mock + private WarpPanelManager wpm; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + // Addon + when(ic.getAddon()).thenReturn(addon); + when(ic.getPermissionPrefix()).thenReturn("bskyblock."); + + // World + when(world.toString()).thenReturn("world"); + + // Player + when(user.getWorld()).thenReturn(world); + + // settings + when(addon.getSettings()).thenReturn(settings); + when(settings.getWarpsCommand()).thenReturn("warps"); + when(settings.getWelcomeLine()).thenReturn(WELCOME_LINE); + + // Warp Signs Manager + when(addon.getWarpSignsManager()).thenReturn(wsm); + @NonNull + Set set = new HashSet<>(); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + set.add(UUID.randomUUID()); + when(wsm.listWarps(eq(world))).thenReturn(set); + + // Warp Panel Manager + when(addon.getWarpPanelManager()).thenReturn(wpm); + + } + + public void warpCommandWarpsCompositeCommand() { + // Command under test + wc = new WarpsCommand(addon, ic); + } + + public void warpCommandWarps() { + // Command under test + wc = new WarpsCommand(addon); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#setup()}. + */ + @Test + public void testSetupWarpCompositeCommand() { + warpCommandWarpsCompositeCommand(); + assertEquals("bskyblock.island.warp", wc.getPermission()); + assertTrue(wc.isOnlyPlayer()); + assertEquals("warps.help.description", wc.getDescription()); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#setup()}. + */ + @Test + public void testSetupWarp() { + warpCommandWarps(); + assertEquals(Warp.WELCOME_WARP_SIGNS + ".warp", wc.getPermission()); + assertTrue(wc.isOnlyPlayer()); + assertEquals("warps.help.description", wc.getDescription()); + } + + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNoWarpsYet() { + when(wsm.listWarps(eq(world))).thenReturn(Collections.emptySet()); + warpCommandWarpsCompositeCommand(); + assertFalse(wc.execute(user, "warps", Collections.emptyList())); + verify(user).sendMessage(eq("warps.error.no-warps-yet")); + verify(user).sendMessage(eq("warps.warpTip"), eq("[text]"), eq(WELCOME_LINE)); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNoWarpsYetNoAddon() { + when(wsm.listWarps(eq(world))).thenReturn(Collections.emptySet()); + warpCommandWarps(); + assertFalse(wc.execute(user, "warps", Collections.emptyList())); + verify(user).sendMessage(eq("warps.error.no-warps-yet")); + verify(user).sendMessage(eq("warps.warpTip"), eq("[text]"), eq(WELCOME_LINE)); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + warpCommandWarpsCompositeCommand(); + assertTrue(wc.execute(user, "warps", Collections.emptyList())); + verify(wpm).showWarpPanel(world, user, 0); + } + + /** + * Test method for {@link world.bentobox.warps.commands.WarpsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNoAddon() { + warpCommandWarps(); + assertTrue(wc.execute(user, "warps", Collections.emptyList())); + verify(wpm).showWarpPanel(world, user, 0); + } + +} From a013a1e6a1034b8760646542fbeedce964699290 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 3 Nov 2019 08:52:29 -0800 Subject: [PATCH 17/17] Version up 1.8.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da4c79c..f9d2ba1 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ -LOCAL - 1.8.0 + 1.8.1