From efc6b795d10819447bbc34a2d8d8c71696d45bb4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 5 Jun 2024 14:09:02 -0700 Subject: [PATCH 01/11] Call events correctly. #131 --- .../bentobox/warps/event/WarpCreateEvent.java | 2 +- .../warps/managers/WarpSignsManager.java | 8 +++- .../bentobox/warps/WarpSignsManagerTest.java | 38 ++++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java b/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java index d9430b9..cd7986a 100644 --- a/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java +++ b/src/main/java/world/bentobox/warps/event/WarpCreateEvent.java @@ -15,7 +15,7 @@ * @author Poslovitch * */ -public class WarpCreateEvent extends Event{ +public class WarpCreateEvent extends Event { private static final HandlerList handlers = new HandlerList(); private final Location warpLoc; diff --git a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java index 2978d8d..450c58c 100644 --- a/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java @@ -38,6 +38,7 @@ import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.util.Util; import world.bentobox.warps.Warp; +import world.bentobox.warps.event.WarpCreateEvent; import world.bentobox.warps.event.WarpInitiateEvent; import world.bentobox.warps.objects.WarpsData; import world.bentobox.warps.panels.Utils; @@ -105,7 +106,7 @@ public boolean addWarp(final UUID playerUUID, final Location loc) { } getWarpMap(loc.getWorld()).put(playerUUID, loc); saveWarpList(); - Bukkit.getPluginManager().callEvent(new WarpInitiateEvent(addon, loc, playerUUID)); + Bukkit.getPluginManager().callEvent(new WarpCreateEvent(addon, loc, playerUUID)); return true; } @@ -350,6 +351,11 @@ private void warpPlayer(@NonNull User user, @NonNull Location inFront, @NonNull float yaw = Util.blockFaceToFloat(directionFacing); final Location actualWarp = new Location(inFront.getWorld(), inFront.getBlockX() + 0.5D, inFront.getBlockY(), inFront.getBlockZ() + 0.5D, yaw, 30F); + WarpInitiateEvent e = new WarpInitiateEvent(addon, actualWarp, user.getUniqueId()); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled()) { + return; + } //BentoBox prevents people from teleporting to an island when //the user is banned from the island for example. //By checking if the teleport succeeded before sending the messages, diff --git a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java index ea51cb0..79ac334 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java @@ -8,7 +8,9 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -40,6 +42,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.stubbing.Answer; @@ -60,6 +63,7 @@ import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.util.Util; import world.bentobox.warps.config.Settings; +import world.bentobox.warps.event.WarpCreateEvent; import world.bentobox.warps.event.WarpInitiateEvent; import world.bentobox.warps.managers.SignCacheManager; import world.bentobox.warps.managers.WarpSignsManager; @@ -349,7 +353,7 @@ public void testAddWarpReplaceOldSignDifferentPlayer() { public void testAddWarp() { Location loc = mock(Location.class); assertTrue(wsm.addWarp(uuid, loc)); - verify(pim).callEvent(any(WarpInitiateEvent.class)); + verify(pim).callEvent(any(WarpCreateEvent.class)); } /** @@ -441,6 +445,38 @@ public void testWarpPlayer() { PowerMockito.verifyStatic(Util.class); Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND)); verify(player).sendMessage(anyString()); + verify(pim).callEvent(any(WarpInitiateEvent.class)); + } + + /** + * Test method for {@link WarpSignsManager#warpPlayer(org.bukkit.World, world.bentobox.bentobox.api.user.User, java.util.UUID)}. + */ + @Test + public void testWarpPlayerEventCancelled() { + // Capture the event passed to callEvent + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(WarpInitiateEvent.class); + + // Simulate the event being called and cancelled + doAnswer(invocation -> { + WarpInitiateEvent event = (WarpInitiateEvent) invocation.getArgument(0); + event.setCancelled(true); + return null; + }).when(pim).callEvent(eventCaptor.capture()); + + Player p = mock(Player.class); + when(p.getUniqueId()).thenReturn(UUID.randomUUID()); + when(p.getWorld()).thenReturn(world); + when(p.getName()).thenReturn("tastybento"); + when(p.getLocation()).thenReturn(location); + when(p.isOnline()).thenReturn(true); + when(p.canSee(any(Player.class))).thenReturn(true); + @Nullable + User u = User.getInstance(p); + PowerMockito.when(Util.teleportAsync(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(true)); + wsm.warpPlayer(world, u, uuid); + PowerMockito.verifyStatic(Util.class, never()); + Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND)); + verify(player, never()).sendMessage(anyString()); } /** From a39b6a3f4a8bb24788306ebb45012cad535ff307 Mon Sep 17 00:00:00 2001 From: RUYSUE <164722481+RUYSUE@users.noreply.github.com> Date: Sat, 8 Jun 2024 17:20:14 +0800 Subject: [PATCH 02/11] Update zh-CN.yml --- src/main/resources/locales/zh-CN.yml | 79 ++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml index adc87c9..a02f446 100644 --- a/src/main/resources/locales/zh-CN.yml +++ b/src/main/resources/locales/zh-CN.yml @@ -1,27 +1,60 @@ ---- +# ########################################################################################## +# 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: 传送到该玩家的传送木牌处 - parameters: "" + description: 传送至对应玩家的坐标告示牌 + parameters: warps: - help: - description: 打开传送面板 - title: 传送木牌 - deactivate: "&c 旧传送牌已停用!" + deactivate: '&c检测到不活跃的坐标告示牌!' error: - does-not-exist: "&c 哦不!那个传送点已经没了!" - no-permission: "&c 你无权那样做!" - no-remove: "&c 你拿不掉那个牌子的!" - no-warps-yet: "&c 暂无可用传送点" - not-enough-level: "&c 你的岛等级不够高!" - not-on-island: "&c 你得在自己的岛屿上操作!" - not-safe: "&c 目标传送点不安全!" - your-level-is: "&c 你的岛现在 [level] 级,需要 [required] 级。 试试岛屿等级命令吧。" - next: "&6 次页" - player-warped: "&2 [name] 传送到了你的传送牌!" - previous: "&6 前页" - random: "&4 随机传送" - sign-removed: "&c 拆掉传送牌了!" - success: "&a 成了!" - warpTip: "&6 放个牌子第一行写 [text]" - warpToPlayersSign: "&6 正传送到 [player] 的牌子" + does-not-exist: '&c啊哦! 那个传送点已经不存在了!' + no-permission: '&c你没有权限做这件事!' + no-remove: '&c你不能移除该告示牌!' + no-warps-yet: '&c尚无可用传送点.' + not-enough-level: '&c你空岛的等级还不够高!' + not-on-island: '&c你必须在自己的空岛上做这件事!' + not-safe: '&c该传送点不安全!' + your-level-is: '&c你空岛的等级只有[level], 但必须高于[required]. 使用/is level查看等级.' + not-correct-rank: '&c你在团队中的地位不足以让你设立传送点!' + help: + description: 打开传送点面板 + player-warped: '&2 [name]传送到了你[gamemode]的坐标告示牌!' + sign-removed: '&c坐标告示牌已移除!' + success: '&a成功!' + warpTip: '&6放置一个顶部为[text]的坐标告示牌' + warpToPlayersSign: '&6正在传送至[player]的坐标告示牌' + + gui: + titles: + # The title of warp panel + warp-title: '&0&l坐标告示牌' + buttons: + # Button that is used in multi-page GUIs which allows to return to previous page. + previous: + name: '&f&l上一页' + description: '&7跳转到第[number]页' # Button that is used in multi-page GUIs which allows to go to next page. + next: + name: '&f&l下一页' + description: '&7跳转到第[number]页' # Button for a warp + warp: + name: '&f&l [name]' + description: '[sign_text]' # Button for a random warp + random: + name: '&f&l随机传送' + description: '&7嗯...我会出现在哪里?' + tips: + click-to-previous: '&e点击&7 查看上一页.' + click-to-next: '&e点击&7 查看下一页.' + click-to-warp: '&e点击&7 进行传送.' + conversations: + # Prefix for messages that are send from server. + prefix: '&l&6 [BentoBox]: &r' + +protection: + flags: + PLACE_WARP: + name: 放置传送点 + description: 允许放置坐标告示牌 From b860a4dac53029baa069e1b58ee781d3c1ce022c Mon Sep 17 00:00:00 2001 From: ISOURA Date: Sat, 8 Jun 2024 17:08:20 +0000 Subject: [PATCH 03/11] Translate fr.yml via GitLocalize --- src/main/resources/locales/fr.yml | 63 +++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/main/resources/locales/fr.yml b/src/main/resources/locales/fr.yml index bf15dcd..a42ee30 100644 --- a/src/main/resources/locales/fr.yml +++ b/src/main/resources/locales/fr.yml @@ -4,25 +4,50 @@ warp: description: te téléporte au Warp d'un autre joueur parameters: "" warps: - deactivate: "&cAncien panneau de Warp désactivé !" + deactivate: "&c Ancienne pancarte de warp désactivée !" 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-on-island: "&cVous devez être sur votre île pour faire cela !" - not-safe: "&cCe Warp n'est pas sûr!" - your-level-is: "&cVotre île est seulement niveau [level] et doit être niveau [required]." + does-not-exist: "&c Oh ! Cette téléportation n'existe plus !" + no-permission: "&c Vous n'avez pas le droit de faire cela !" + no-remove: "&c Vous ne pouvez pas enlever cette pancarte !" + no-warps-yet: "&c Il n'y a pas encore de téléportation disponible" + not-enough-level: "&c Le niveau de votre île n'est pas assez élevé !" + not-on-island: "&c Vous devez être sur votre île pour faire cela !" + not-safe: "&c Cette téléportation n'est pas sûre !" + your-level-is: "&c Le niveau de votre île n'est que [level] et doit être supérieur + à [required]. Exécutez la commande level." + not-correct-rank: "&c Vous n'avez pas le grade adéquat pour poser une chaîne !" help: description: Ouvre le menu des Warps - next: "&6Page suivante" - player-warped: "& 2 [pseudo] s'est téléporté à votre panneau Warp !" - previous: "&6Page précédente" - random: "&4 Warp aléatoire " - sign-removed: "&cPanneau de Warp supprimé !" - success: "&aSuccès !" - title: Panneau Warp - warpTip: "&6Placez un panneau et écrivez [text] sur la première ligne." - warpToPlayersSign: "&6 Téléportation vers le panneau de [pseudo]" + player-warped: "&2 [name] s'est rendu à votre pancarte de téléportation [gamemode] + !" + sign-removed: "&c Panneau de téléportation enlevé !" + success: "&a Succès !" + warpTip: "&6 Placer une pancarte de téléportation avec [text] sur le dessus" + warpToPlayersSign: "&6 Téléportation a la pancarte de [player]" + gui: + titles: + warp-title: "&0&l Pancarte de téléportation" + buttons: + previous: + name: "&f&l Page précédente" + description: "&7 Aller à la page [numéro]." + next: + name: "&f&l Page suivante" + description: "&7 Passer à la page [numéro]." + warp: + name: "&f&l [name]" + description: "[sign_text]" + random: + name: "&f&l Téléportation aléatoire" + description: "&7 Hmm, où vais-je apparaître ?" + tips: + click-to-previous: "&e Cliquez sur &7 pour afficher la page précédente." + click-to-next: "&e Cliquez sur &7 pour afficher la page suivante." + click-to-warp: "&e Cliquez sur &7 pour te téléporter." + conversations: + prefix: "&l&6 [BentoBox]: &r" +protection: + flags: + PLACE_WARP: + name: Place téléportation + description: Autoriser le placement d'un panneau téléportation From 0a343219bc3419dfda016f37b92e20932186fd4a Mon Sep 17 00:00:00 2001 From: TreemanK Date: Thu, 20 Jun 2024 21:57:50 +1000 Subject: [PATCH 04/11] 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 05/11] 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 06/11] 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 07/11] 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 08/11] 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 1054518831f7387a59094ecae9f7e45e3e18565e Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 22:51:00 +1000 Subject: [PATCH 09/11] fix: fix create warp/sign in non-island world Currently, you can't create a warp in another world (even with permissions) as it goes into hasCorrectIslandRank. In this case, it is always false as there is no island at the block location meaning it will always go into this whilst creating a warp in other worlds. --- .../java/world/bentobox/warps/listeners/WarpSignsListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java index dce3236..80bcdf8 100644 --- a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java @@ -163,7 +163,7 @@ public void onSignWarpCreate(SignChangeEvent e) { return; } - if(!hasCorrectIslandRank(b, user)) { + if (inWorld && !hasCorrectIslandRank(b, user)) { e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); user.sendMessage("warps.error.not-correct-rank"); return; From 599a6e1d0870bf8cbaaefb4c02bd67a84d5d8a53 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Fri, 21 Jun 2024 23:57:24 +1000 Subject: [PATCH 10/11] style: added TODO Currently, `noLevelOrIsland and hasCorrectIslandRank` require the sign to be on an island. Currently this means the flag/level requirement are non-existent in the case of a sign being placed on a non-BSB island. This gives a possible solution if new API comes to light. --- .../world/bentobox/warps/listeners/WarpSignsListener.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java index 80bcdf8..5f25076 100644 --- a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java +++ b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java @@ -158,6 +158,11 @@ public void onSignWarpCreate(SignChangeEvent e) { if (noPerms(user, b.getWorld(), inWorld)) { return; } + // TODO: These checks are useless if the sign is placed outside a BSB world. + // This will mean level and rank requirements are nil in the case of allow-in-other-worlds: true. + // I'm not sure if there is a better way around this without adding new API checking for primary + // or last island accessed with relevant permissions. + // ignored. if (inWorld && noLevelOrIsland(user, b.getWorld())) { e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); return; From 4bacbd7c5a48c28dd44f980c8897cea3f5fa18d3 Mon Sep 17 00:00:00 2001 From: TreemanK Date: Sat, 22 Jun 2024 13:16:47 +1000 Subject: [PATCH 11/11] 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) {