From 0a343219bc3419dfda016f37b92e20932186fd4a Mon Sep 17 00:00:00 2001 From: TreemanK Date: Thu, 20 Jun 2024 21:57:50 +1000 Subject: [PATCH 1/6] feat: changed location to playerwarp in preparation of toggle state --- .../warps/listeners/WarpSignsListener.java | 19 +++++----- .../warps/managers/WarpSignsManager.java | 37 +++++++++++-------- .../bentobox/warps/objects/PlayerWarp.java | 32 ++++++++++++++++ .../bentobox/warps/objects/WarpsData.java | 13 +++---- .../world/bentobox/warps/panels/Utils.java | 2 +- .../bentobox/warps/WarpSignsManagerTest.java | 6 ++- .../listeners/WarpSignsListenerTest.java | 9 +++-- 7 files changed, 79 insertions(+), 39 deletions(-) create mode 100644 src/main/java/world/bentobox/warps/objects/PlayerWarp.java diff --git a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java index dce3236..b881551 100644 --- a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java @@ -28,6 +28,7 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.util.Util; +import world.bentobox.warps.objects.PlayerWarp; import world.bentobox.warps.Warp; import world.bentobox.warps.event.WarpRemoveEvent; @@ -60,12 +61,12 @@ public void onChunkLoad(ChunkLoadEvent event) { @Override public void run() { boolean changed = false; - Iterator> iterator = + Iterator> iterator = addon.getWarpSignsManager().getWarpMap(event.getWorld()).entrySet().iterator(); while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); + Map.Entry entry = iterator.next(); UUID uuid = entry.getKey(); - Location location = entry.getValue(); + Location location = entry.getValue().getLocation(); if (event.getChunk().getX() == location.getBlockX() >> 4 && event.getChunk().getZ() == location.getBlockZ() >> 4 && !Tag.SIGNS.isTagged(location.getBlock().getType())) { @@ -126,16 +127,16 @@ public void onSignBreak(BlockBreakEvent e) { 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()); + 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())) + return ((list.containsKey(player.getUniqueId()) && list.get(player.getUniqueId()).getLocation().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()); + && addon.getWarpSignsManager().getWarpMap(b.getWorld()).values().stream().anyMatch(playerWarp -> playerWarp.getLocation().equals(s.getLocation())); } /** @@ -216,15 +217,15 @@ public void onFlagChange(FlagProtectionChangeEvent e) { final Island island = e.getIsland(); - final Map islandWarps = addon + final Map islandWarps = addon .getWarpSignsManager() .getWarpMap(island.getWorld()) .entrySet() .stream() - .filter(x -> island.inIslandSpace(x.getValue())) + .filter(x -> island.inIslandSpace(x.getValue().getLocation())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - for(Map.Entry entry : islandWarps.entrySet()) { + for(Map.Entry entry : islandWarps.entrySet()) { if(island.getRank(entry.getKey()) >= e.getSetTo()) continue; //The user has a lower rank than the new set value. diff --git a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java index 450c58c..efc96ed 100644 --- a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java @@ -37,6 +37,7 @@ import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.util.Util; +import world.bentobox.warps.objects.PlayerWarp; import world.bentobox.warps.Warp; import world.bentobox.warps.event.WarpCreateEvent; import world.bentobox.warps.event.WarpInitiateEvent; @@ -55,7 +56,7 @@ public class WarpSignsManager { private static final String WARPS = "warps"; private final BentoBox plugin; // Map of all warps stored as player, warp sign Location - private Map> worldsWarpList; + private Map> worldsWarpList; // Database handler for level data private final Database handler; @@ -68,7 +69,7 @@ public class WarpSignsManager { * @return map of warps */ @NonNull - public Map getWarpMap(@Nullable World world) { + public Map getWarpMap(@Nullable World world) { return worldsWarpList.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()); } @@ -100,11 +101,13 @@ public boolean addWarp(final UUID playerUUID, final Location loc) { return false; } // Check for warps placed in a location where there was a warp before - if (getWarpMap(loc.getWorld()).containsValue(loc)) { - // remove the warp at this location, then place it - this.removeWarp(loc); + for (PlayerWarp playerWarp : getWarpMap(loc.getWorld()).values()) { + if (playerWarp.getLocation().equals(loc)) { + this.removeWarp(loc); + break; + } } - getWarpMap(loc.getWorld()).put(playerUUID, loc); + getWarpMap(loc.getWorld()).put(playerUUID, new PlayerWarp(loc, true)); saveWarpList(); Bukkit.getPluginManager().callEvent(new WarpCreateEvent(addon, loc, playerUUID)); return true; @@ -120,7 +123,8 @@ public boolean addWarp(final UUID playerUUID, final Location loc) { */ @Nullable public Location getWarp(World world, UUID playerUUID) { - return getWarpMap(world).get(playerUUID); + PlayerWarp playerWarp = getWarpMap(world).get(playerUUID); + return playerWarp != null ? playerWarp.getLocation() : null; } /** @@ -130,7 +134,7 @@ public Location getWarp(World world, UUID playerUUID) { */ @NonNull public String getWarpOwner(Location location) { - return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().equals(location)) + return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().getLocation().equals(location)) .findFirst().map(en -> plugin.getPlayers().getName(en.getKey())).orElse(""); } @@ -140,7 +144,7 @@ public String getWarpOwner(Location location) { * @return Optional UUID of warp owner or empty if there is none */ public Optional getWarpOwnerUUID(Location location) { - return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().equals(location)) + return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().getLocation().equals(location)) .findFirst().map(Map.Entry::getKey); } @@ -188,7 +192,7 @@ public List processWarpMap(CompletableFuture> r, @NonNull World 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, Objects.requireNonNull(e.getValue().getWorld()))).map(Map.Entry::getKey).collect(Collectors.toSet()); + return getWarpMap(world).entrySet().stream().filter(e -> Util.sameWorld(world, Objects.requireNonNull(e.getValue().getLocation().getWorld()))).map(Map.Entry::getKey).collect(Collectors.toSet()); } /** @@ -201,7 +205,8 @@ public void loadWarpList() { warpsData = handler.loadObject(WARPS); // Load into map if (warpsData != null) { - warpsData.getWarpSigns().forEach((location,uuid) -> { + warpsData.getWarpSigns().forEach((pw, uuid) -> { + Location location = pw.getLocation(); if (location != null && location.getWorld() != null) { if (location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4) && !location.getBlock().getType().name().contains("SIGN")) { @@ -209,7 +214,7 @@ public void loadWarpList() { } // Add to map - getWarpMap(location.getWorld()).put(uuid, location); + getWarpMap(location.getWorld()).put(uuid, new PlayerWarp(location, true)); } }); } else { @@ -240,10 +245,10 @@ private void popSign(Location loc) { */ public void removeWarp(Location loc) { popSign(loc); - Iterator> it = getWarpMap(loc.getWorld()).entrySet().iterator(); + Iterator> it = getWarpMap(loc.getWorld()).entrySet().iterator(); while (it.hasNext()) { - Entry en = it.next(); - if (en.getValue().equals(loc)) { + Entry en = it.next(); + if (en.getValue().getLocation().equals(loc)) { // Inform player Optional.ofNullable(addon.getServer().getPlayer(en.getKey())) .map(User::getInstance) @@ -263,7 +268,7 @@ public void removeWarp(Location loc) { */ public void removeWarp(World world, UUID uuid) { if (getWarpMap(world).containsKey(uuid)) { - popSign(getWarpMap(world).get(uuid)); + popSign(getWarpMap(world).get(uuid).getLocation()); getWarpMap(world).remove(uuid); } diff --git a/src/main/java/world/bentobox/warps/objects/PlayerWarp.java b/src/main/java/world/bentobox/warps/objects/PlayerWarp.java new file mode 100644 index 0000000..d12b582 --- /dev/null +++ b/src/main/java/world/bentobox/warps/objects/PlayerWarp.java @@ -0,0 +1,32 @@ +package world.bentobox.warps.objects; + +import com.google.gson.annotations.Expose; +import org.bukkit.Location; + +import java.io.Serializable; + +public class PlayerWarp implements Serializable { + + @Expose + private final Location location; + + @Expose + private boolean isEnabled; + + public PlayerWarp(Location location, boolean isEnabled) { + this.location = location; + this.isEnabled = isEnabled; + } + + public Location getLocation() { + return location; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void toggle() { + isEnabled = !isEnabled; + } +} diff --git a/src/main/java/world/bentobox/warps/objects/WarpsData.java b/src/main/java/world/bentobox/warps/objects/WarpsData.java index a09f22d..a1dd1ae 100644 --- a/src/main/java/world/bentobox/warps/objects/WarpsData.java +++ b/src/main/java/world/bentobox/warps/objects/WarpsData.java @@ -4,7 +4,6 @@ import java.util.Map; import java.util.UUID; -import org.bukkit.Location; import org.bukkit.World; import com.google.gson.annotations.Expose; @@ -18,7 +17,7 @@ public class WarpsData implements DataObject { @Expose private String uniqueId = "warps"; @Expose - private Map warpSigns = new HashMap<>(); + private Map warpSigns = new HashMap<>(); public WarpsData() { // Required by YAML database @@ -34,24 +33,24 @@ public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; } - public Map getWarpSigns() { + public Map getWarpSigns() { if (warpSigns == null) return new HashMap<>(); return warpSigns; } - public void setWarpSigns(Map warpSigns) { + public void setWarpSigns(Map warpSigns) { this.warpSigns = warpSigns; } /** - * Puts all the data from the map into this objects ready for saving + * Puts all the data from the map into these objects ready for saving * @param worldsWarpList 2D map of warp locations by world vs UUID * @return this class filled with data */ - public WarpsData save(Map> worldsWarpList) { + public WarpsData save(Map> worldsWarpList) { getWarpSigns().clear(); - worldsWarpList.values().forEach(world -> world.forEach((uuid,location) -> warpSigns.put(location, uuid))); + worldsWarpList.values().forEach(world -> world.forEach((uuid,playerWarp) -> warpSigns.put(playerWarp, uuid))); return this; } diff --git a/src/main/java/world/bentobox/warps/panels/Utils.java b/src/main/java/world/bentobox/warps/panels/Utils.java index 2c4b8c8..b9ac27a 100644 --- a/src/main/java/world/bentobox/warps/panels/Utils.java +++ b/src/main/java/world/bentobox/warps/panels/Utils.java @@ -52,7 +52,7 @@ public static String getPermissionValue(User user, String permissionPrefix, Stri List permissions = user.getEffectivePermissions().stream(). map(PermissionAttachmentInfo::getPermission). filter(permission -> permission.startsWith(permPrefix)). - collect(Collectors.toList()); + toList(); for (String permission : permissions) { diff --git a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java index 79ac334..c82741a 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java @@ -67,6 +67,7 @@ import world.bentobox.warps.event.WarpInitiateEvent; import world.bentobox.warps.managers.SignCacheManager; import world.bentobox.warps.managers.WarpSignsManager; +import world.bentobox.warps.objects.PlayerWarp; import world.bentobox.warps.objects.WarpsData; @@ -195,7 +196,7 @@ public void setUp() throws Exception { // Handler when(handler.objectExists("warps")).thenReturn(true); - Map warpMap = Collections.singletonMap(location, uuid); + Map warpMap = Collections.singletonMap(new PlayerWarp(location, true), uuid); when(load.getWarpSigns()).thenReturn(warpMap); when(handler.loadObject(anyString())).thenReturn(load); @@ -275,7 +276,8 @@ public void testGetWarpMapWrongBlockType() { */ @Test public void testGetWarpMapNullLocation() { - Map warpMap = Collections.singletonMap(null, uuid); + PlayerWarp playerWarp = new PlayerWarp(null, true); + Map warpMap = Collections.singletonMap(playerWarp, uuid); when(load.getWarpSigns()).thenReturn(warpMap); wsm = new WarpSignsManager(addon, plugin); assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); diff --git a/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java b/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java index f98d1be..d90c3e0 100644 --- a/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java +++ b/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java @@ -50,6 +50,7 @@ import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.util.Util; +import world.bentobox.warps.objects.PlayerWarp; import world.bentobox.warps.Warp; import world.bentobox.warps.managers.WarpSignsManager; import world.bentobox.warps.config.Settings; @@ -123,12 +124,12 @@ public void setUp() { when(block.getState()).thenReturn(s); // warp signs manager when(addon.getWarpSignsManager()).thenReturn(wsm); - Map list = new HashMap<>(); + Map list = new HashMap<>(); Location location = mock(Location.class); when(location.getBlock()).thenReturn(block); when(s.getLocation()).thenReturn(location); when(block.getLocation()).thenReturn(location); - list.put(uuid, location); + list.put(uuid, new PlayerWarp(location, true)); // Player is in world when(wsm.getWarpMap(world)).thenReturn(list); //Player has a warp sign already here @@ -339,8 +340,8 @@ public void testOnFlagChangeWhenSettingIsOnWarpGetsRemoved() { when(settings.getRemoveExistingWarpsWhenFlagChanges()).thenReturn(true); WarpSignsListener wsl = new WarpSignsListener(addon); - Map warps = Map.of( - player.getUniqueId(), block.getLocation() + Map warps = Map.of( + player.getUniqueId(), new PlayerWarp(block.getLocation(), true) ); when(wsm.getWarpMap(any())).thenReturn(warps); From 64f8a4899a9d55d2f9c03d184d77659b0cfd44c0 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 01:49:30 +1000 Subject: [PATCH 2/6] feat: make sure old data is not lost! Now, I was thinking if there is a way to directly convert it but there isn't because of the way it was structured. This *ISN'T* the best way around things but if someone can find a better way around it, be my guest. --- .../bentobox/warps/objects/WarpsData.java | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/java/world/bentobox/warps/objects/WarpsData.java b/src/main/java/world/bentobox/warps/objects/WarpsData.java index a1dd1ae..7743df6 100644 --- a/src/main/java/world/bentobox/warps/objects/WarpsData.java +++ b/src/main/java/world/bentobox/warps/objects/WarpsData.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.UUID; +import org.bukkit.Location; import org.bukkit.World; import com.google.gson.annotations.Expose; @@ -16,8 +17,12 @@ public class WarpsData implements DataObject { @Expose private String uniqueId = "warps"; + + @Deprecated @Expose + private Map warpSigns = new HashMap<>(); + @Expose - private Map warpSigns = new HashMap<>(); + private Map newWarpSigns = new HashMap<>(); public WarpsData() { // Required by YAML database @@ -34,13 +39,28 @@ public void setUniqueId(String uniqueId) { } public Map getWarpSigns() { - if (warpSigns == null) + convertOldWarpSigns(); + if (newWarpSigns == null) return new HashMap<>(); - return warpSigns; + return newWarpSigns; + } + + /** + * Method for converting old warp signs to new warp signs + */ + public void convertOldWarpSigns() { + if (warpSigns == null) { + return; + } + + for (Map.Entry entry : warpSigns.entrySet()) { + PlayerWarp playerWarp = new PlayerWarp(entry.getKey(), true); + newWarpSigns.put(playerWarp, entry.getValue()); + } } public void setWarpSigns(Map warpSigns) { - this.warpSigns = warpSigns; + this.newWarpSigns = warpSigns; } /** @@ -50,7 +70,7 @@ public void setWarpSigns(Map warpSigns) { */ public WarpsData save(Map> worldsWarpList) { getWarpSigns().clear(); - worldsWarpList.values().forEach(world -> world.forEach((uuid,playerWarp) -> warpSigns.put(playerWarp, uuid))); + worldsWarpList.values().forEach(world -> world.forEach((uuid,playerWarp) -> newWarpSigns.put(playerWarp, uuid))); return this; } From ef81a1c2f01a902bba6e78a9a0fdd4eee9d631b2 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 02:23:38 +1000 Subject: [PATCH 3/6] style: change method name to getWarpLocation note `line 294` of `warp.java`, I am unsure what this does and whether it should be `getWarpLocation` or not. I will leave it for the time being. --- src/main/java/world/bentobox/warps/Warp.java | 2 +- .../bentobox/warps/listeners/WarpSignsListener.java | 2 +- .../bentobox/warps/managers/WarpSignsManager.java | 11 ++++++++--- .../java/world/bentobox/warps/objects/WarpsData.java | 1 + .../world/bentobox/warps/WarpSignsManagerTest.java | 8 ++++---- .../warps/listeners/WarpSignsListenerTest.java | 4 ++-- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 1cbdd71..63a6ed1 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -288,7 +288,7 @@ public Object request(String requestLabel, Map metaData) { } return switch (requestLabel) { case "getSortedWarps" -> getWarpSignsManager().getSortedWarps(world); - case "getWarp" -> uuid == null ? null : getWarpSignsManager().getWarp(world, uuid); + case "getWarp" -> uuid == null ? null : getWarpSignsManager().getWarpLocation(world, uuid); case "getWarpMap" -> getWarpSignsManager().getWarpMap(world); case "hasWarp" -> uuid == null ? null : getWarpSignsManager().hasWarp(world, uuid); case "listWarps" -> getWarpSignsManager().listWarps(world); diff --git a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java index b881551..2c4cb5b 100644 --- a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java @@ -171,7 +171,7 @@ public void onSignWarpCreate(SignChangeEvent e) { } // Check if the player already has a sign - final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId()); + final Location oldSignLoc = addon.getWarpSignsManager().getWarpLocation(b.getWorld(), user.getUniqueId()); if (oldSignLoc != null) { // A sign already exists. Check if it still there and if // so, diff --git a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java index efc96ed..3ae6565 100644 --- a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java @@ -122,11 +122,16 @@ public boolean addWarp(final UUID playerUUID, final Location loc) { * @return Location of warp or null */ @Nullable - public Location getWarp(World world, UUID playerUUID) { + public Location getWarpLocation(World world, UUID playerUUID) { PlayerWarp playerWarp = getWarpMap(world).get(playerUUID); return playerWarp != null ? playerWarp.getLocation() : null; } + @Nullable + public PlayerWarp getPlayerWarp(World world, UUID playerUUID) { + return getWarpMap(world).get(playerUUID); + } + /** * Get the name of the warp owner by location * @param location to search @@ -304,7 +309,7 @@ public void saveWarpList() { @NonNull public SignCacheItem getSignInfo(@NonNull World world, @NonNull UUID uuid) { //get the sign info - Location signLocation = getWarp(world, uuid); + Location signLocation = getWarpLocation(world, uuid); if (signLocation == null || !signLocation.getBlock().getType().name().contains("SIGN")) { return new SignCacheItem(); } @@ -398,7 +403,7 @@ private void warpPlayer(@NonNull User user, @NonNull Location inFront, @NonNull * @param owner - owner of the warp */ public void warpPlayer(@NonNull World world, @NonNull User user, @NonNull UUID owner) { - final Location warpSpot = getWarp(world, owner); + final Location warpSpot = getWarpLocation(world, owner); // Check if the warp spot is safe if (warpSpot == null) { user.sendMessage("warps.error.does-not-exist"); diff --git a/src/main/java/world/bentobox/warps/objects/WarpsData.java b/src/main/java/world/bentobox/warps/objects/WarpsData.java index 7743df6..dfbdd4d 100644 --- a/src/main/java/world/bentobox/warps/objects/WarpsData.java +++ b/src/main/java/world/bentobox/warps/objects/WarpsData.java @@ -57,6 +57,7 @@ public void convertOldWarpSigns() { PlayerWarp playerWarp = new PlayerWarp(entry.getKey(), true); newWarpSigns.put(playerWarp, entry.getValue()); } + warpSigns.clear(); } public void setWarpSigns(Map warpSigns) { diff --git a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java index c82741a..a6e3eb2 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java @@ -359,19 +359,19 @@ public void testAddWarp() { } /** - * Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. + * Test method for {@link WarpSignsManager#getWarpLocation(org.bukkit.World, java.util.UUID)}. */ @Test public void testGetWarpWorldWorld() { - assertNull(wsm.getWarp(mock(World.class), uuid)); + assertNull(wsm.getWarpLocation(mock(World.class), uuid)); } /** - * Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. + * Test method for {@link WarpSignsManager#getWarpLocation(org.bukkit.World, java.util.UUID)}. */ @Test public void testGetWarp() { - assertEquals(location, wsm.getWarp(world, uuid)); + assertEquals(location, wsm.getWarpLocation(world, uuid)); } /** diff --git a/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java b/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java index d90c3e0..66c15b2 100644 --- a/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java +++ b/src/test/java/world/bentobox/warps/listeners/WarpSignsListenerTest.java @@ -133,7 +133,7 @@ public void setUp() { // Player is in world when(wsm.getWarpMap(world)).thenReturn(list); //Player has a warp sign already here - when(wsm.getWarp(any(), any())).thenReturn(location); + when(wsm.getWarpLocation(any(), any())).thenReturn(location); // Unique spot when(wsm.addWarp(any(), any())).thenReturn(true); // Bentobox @@ -421,7 +421,7 @@ public void testOnNoIsland() { @Test public void testCreateNoSignAlreadyUniqueSpot() { - when(wsm.getWarp(any(), any())).thenReturn(null); + when(wsm.getWarpLocation(any(), any())).thenReturn(null); when(player.hasPermission(anyString())).thenReturn(true); WarpSignsListener wsl = new WarpSignsListener(addon); SignChangeEvent e = new SignChangeEvent(block, player, lines); From eeead7fb49041399c1675a9cf5ce97f85b58ef57 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 20:19:24 +1000 Subject: [PATCH 4/6] feat: toggle warp command --- src/main/java/world/bentobox/warps/Warp.java | 3 + .../warps/commands/ToggleWarpCommand.java | 58 +++++++++++++++++++ .../bentobox/warps/commands/WarpCommand.java | 4 +- .../world/bentobox/warps/config/Settings.java | 17 ++++++ .../warps/managers/WarpSignsManager.java | 10 +++- src/main/resources/addon.yml | 3 + src/main/resources/config.yml | 1 + src/main/resources/locales/en-US.yml | 10 ++++ 8 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 63a6ed1..e48f2a1 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -17,6 +17,7 @@ import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; import world.bentobox.level.Level; +import world.bentobox.warps.commands.ToggleWarpCommand; import world.bentobox.warps.commands.WarpCommand; import world.bentobox.warps.commands.WarpsCommand; import world.bentobox.warps.config.Settings; @@ -100,6 +101,7 @@ public void onLoad() // Load the master warp and warps command new WarpCommand(this); new WarpsCommand(this); + new ToggleWarpCommand(this); } } @@ -140,6 +142,7 @@ public void onEnable() { new WarpCommand(this, gameModeAddon.getPlayerCommand().get()); new WarpsCommand(this, gameModeAddon.getPlayerCommand().get()); + new ToggleWarpCommand(this, gameModeAddon.getPlayerCommand().get()); this.hooked = true; } }); diff --git a/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java b/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java new file mode 100644 index 0000000..a4823ad --- /dev/null +++ b/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java @@ -0,0 +1,58 @@ +package world.bentobox.warps.commands; + +import org.bukkit.World; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.warps.Warp; +import world.bentobox.warps.objects.PlayerWarp; + +import java.util.List; +import java.util.UUID; + +public class ToggleWarpCommand extends CompositeCommand { + + private final Warp addon; + + public ToggleWarpCommand(Warp addon, CompositeCommand bsbIslandCmd) { + super(bsbIslandCmd, addon.getSettings().getToggleWarpCommand()); + this.addon = addon; + } + + public ToggleWarpCommand(Warp addon) { + super(addon.getSettings().getToggleWarpCommand()); + this.addon = addon; + } + + + @Override + public void setup() { + this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".togglewarp" : "island.warp.toggle"); + this.setOnlyPlayer(true); + this.setDescription("togglewarp.help.description"); + } + + @Override + public boolean execute(User user, String s, List list) { + UUID userUUID = user.getUniqueId(); + World userWorld = user.getWorld(); + + // Check if the user has a warp + boolean hasWarp = addon.getWarpSignsManager().hasWarp(userWorld, userUUID); + + if (hasWarp) { + // If the user has a warp, toggle its visibility + PlayerWarp warp = addon.getWarpSignsManager().getPlayerWarp(userWorld, userUUID); + // Check extreme case if PlayerWarp is null + if (warp == null) { + user.sendMessage("togglewarp.error.generic"); + return false; + } + warp.toggle(); + String message = warp.isEnabled() ? "togglewarp.enabled" : "togglewarp.disabled"; + user.sendMessage(message); + } else { + user.sendMessage("togglewarp.error.no-warp"); + } + return false; + } +} diff --git a/src/main/java/world/bentobox/warps/commands/WarpCommand.java b/src/main/java/world/bentobox/warps/commands/WarpCommand.java index 53af311..bb4e445 100644 --- a/src/main/java/world/bentobox/warps/commands/WarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/WarpCommand.java @@ -50,12 +50,12 @@ public boolean execute(User user, String label, List args) { user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); return false; } else { - // Attemp to find warp with exact player's name + // Attempt to find warp with exact player's name UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).equalsIgnoreCase(args.get(0))).findFirst().orElse(null); if (foundWarp == null) { - // Atempt to find warp which starts with the given name + // Attempt to find warp which starts with the given name UUID foundAlernativeWarp = warpList.stream().filter(u -> getPlayers().getName(u).toLowerCase().startsWith(args.get(0).toLowerCase())).findFirst().orElse(null); if (foundAlernativeWarp == null) { diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java index 883687b..85f90ae 100644 --- a/src/main/java/world/bentobox/warps/config/Settings.java +++ b/src/main/java/world/bentobox/warps/config/Settings.java @@ -61,6 +61,8 @@ public class Settings implements ConfigObject String warpCommand = "warp"; @ConfigEntry(path = "warps-command") String warpsCommand = "warps"; + @ConfigEntry(path = "togglewarp-command") + String toggleWarpCommand = "togglewarp"; // --------------------------------------------------------------------- // Section: Constructor @@ -205,6 +207,21 @@ public void setWarpsCommand(String warpsCommand) { this.warpsCommand = warpsCommand; } + + /** + * @return the toggleWarpCommand + */ + public String getToggleWarpCommand() { + return "togglewarp"; + } + + /** + * @param toggleWarpCommand the toggleWarpCommand to set + */ + public void setToggleWarpCommand(String toggleWarpCommand) { + this.toggleWarpCommand = toggleWarpCommand; + } + /** * @return the removeExistingWarpsWhenFlagChanges */ diff --git a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java index 3ae6565..18a7773 100644 --- a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java @@ -169,6 +169,10 @@ public List processWarpMap(CompletableFuture> r, @NonNull World // Bigger value of time means a more recent login TreeMap map = new TreeMap<>(); getWarpMap(world).forEach((uuid, value) -> { + // If the warp is not enabled, skip this iteration + if (!value.isEnabled()) { + return; + } // If never played, will be zero long lastPlayed = addon.getServer().getOfflinePlayer(uuid).getLastPlayed(); // This aims to avoid the chance that players logged off at exactly the same time @@ -197,7 +201,11 @@ public List processWarpMap(CompletableFuture> r, @NonNull World 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, Objects.requireNonNull(e.getValue().getLocation().getWorld()))).map(Map.Entry::getKey).collect(Collectors.toSet()); + // Remove any warps that have not been toggled on + Map enabledWarps = getWarpMap(world).entrySet().stream() + .filter(entry -> entry.getValue().isEnabled()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return enabledWarps.keySet(); } /** diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index a75733f..b8de846 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -18,3 +18,6 @@ permissions: '[gamemode].island.addwarp': description: Player can create a welcome warp sign default: true + '[gamemode].island.togglewarp': + description: Player can toggle a warp sign + default: true diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 1975fd0..42c4d4a 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -33,3 +33,4 @@ 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 +togglewarp-command: togglewarp diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 7198653..c48efee 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -60,6 +60,16 @@ warps: # Prefix for messages that are send from server. prefix: "&l&6 [BentoBox]: &r" +togglewarp: + help: + description: "toggle the warp sign" + enabled: "&a Your warp is now visible!" + disabled: "&c Your warp is now hidden!" + error: + no-permission: "&c You do not have permission to do that!" + generic: "&c An error occurred while toggling your warp." + no-warp: "&c You do not have a warp to toggle!" + protection: flags: PLACE_WARP: From abd526b06df1fff2433e6bf5b9039fd91ab5a4f3 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 20:42:31 +1000 Subject: [PATCH 5/6] feat: add toggle event --- .../warps/commands/ToggleWarpCommand.java | 3 + .../bentobox/warps/event/WarpToggleEvent.java | 72 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/main/java/world/bentobox/warps/event/WarpToggleEvent.java diff --git a/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java b/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java index a4823ad..4885697 100644 --- a/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java +++ b/src/main/java/world/bentobox/warps/commands/ToggleWarpCommand.java @@ -1,9 +1,11 @@ package world.bentobox.warps.commands; +import org.bukkit.Bukkit; import org.bukkit.World; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.warps.Warp; +import world.bentobox.warps.event.WarpToggleEvent; import world.bentobox.warps.objects.PlayerWarp; import java.util.List; @@ -48,6 +50,7 @@ public boolean execute(User user, String s, List list) { return false; } warp.toggle(); + Bukkit.getPluginManager().callEvent(new WarpToggleEvent(userUUID, warp)); String message = warp.isEnabled() ? "togglewarp.enabled" : "togglewarp.disabled"; user.sendMessage(message); } else { diff --git a/src/main/java/world/bentobox/warps/event/WarpToggleEvent.java b/src/main/java/world/bentobox/warps/event/WarpToggleEvent.java new file mode 100644 index 0000000..b4f0460 --- /dev/null +++ b/src/main/java/world/bentobox/warps/event/WarpToggleEvent.java @@ -0,0 +1,72 @@ +package world.bentobox.warps.event; + +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import world.bentobox.warps.objects.PlayerWarp; + +import java.util.UUID; + +/** + * This event is fired when a warp is toggled + * A Listener to this event can use it only to get information. e.g: broadcast something + * + * @since 1.16.0 + * @author TreemanKing + */ +public class WarpToggleEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private final UUID user; + private final PlayerWarp playerWarp; + + public WarpToggleEvent(UUID user, PlayerWarp playerWarp) { + this.playerWarp = playerWarp; + this.user = user; + } + + /** + * Gets the user who has toggled the warp + * + * @return the UUID of the player who toggled the warp + */ + public UUID getUser() { + return user; + } + + /** + * Gets the state of the warp + * + * @return true if the warp is enabled, false otherwise + */ + public boolean isEnabled() { + return playerWarp.isEnabled(); + } + + /** + * Gets the PlayerWarp object + * + * @return the PlayerWarp object + */ + public PlayerWarp getPlayerWarp() { + return playerWarp; + } + + /** + * Gets the location of the toggled warp + * + * @return the location of the warp + */ + public Location getLocation() { + return playerWarp.getLocation(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} From 4bacbd7c5a48c28dd44f980c8897cea3f5fa18d3 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Sat, 22 Jun 2024 13:16:47 +1000 Subject: [PATCH 6/6] feat: suggestions - getToggleCommand is linked to toggleWarpCommand instead of hardcoded - warpSigns is now null and not empty --- src/main/java/world/bentobox/warps/config/Settings.java | 2 +- src/main/java/world/bentobox/warps/objects/WarpsData.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java index 85f90ae..b0bb4ba 100644 --- a/src/main/java/world/bentobox/warps/config/Settings.java +++ b/src/main/java/world/bentobox/warps/config/Settings.java @@ -212,7 +212,7 @@ public void setWarpsCommand(String warpsCommand) { * @return the toggleWarpCommand */ public String getToggleWarpCommand() { - return "togglewarp"; + return toggleWarpCommand; } /** diff --git a/src/main/java/world/bentobox/warps/objects/WarpsData.java b/src/main/java/world/bentobox/warps/objects/WarpsData.java index dfbdd4d..9d17cdf 100644 --- a/src/main/java/world/bentobox/warps/objects/WarpsData.java +++ b/src/main/java/world/bentobox/warps/objects/WarpsData.java @@ -57,7 +57,7 @@ public void convertOldWarpSigns() { PlayerWarp playerWarp = new PlayerWarp(entry.getKey(), true); newWarpSigns.put(playerWarp, entry.getValue()); } - warpSigns.clear(); + warpSigns = null; } public void setWarpSigns(Map warpSigns) {