From 23029d1cfd0940a000e8071703a79ace8b222a7e Mon Sep 17 00:00:00 2001 From: IAISI <126729304+IAISI@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:27:55 +0100 Subject: [PATCH] Add min level required /is fly usage (#115) * Add min level required /is fly usage * Fix missing methods and inspect errors --------- Co-authored-by: Dieu --- pom.xml | 8 ++++ .../bentobox/islandfly/FlyToggleCommand.java | 16 ++++++-- .../bentobox/islandfly/IslandFlyAddon.java | 39 ++++++++++++++++--- .../bentobox/islandfly/config/Settings.java | 23 ++++++++--- .../islandfly/listeners/FlyDeathListener.java | 7 ++-- .../islandfly/listeners/FlyFlagListener.java | 1 - .../islandfly/listeners/FlyListener.java | 36 ++++++++++------- .../islandfly/listeners/FlyLoginListener.java | 26 ++++++++----- .../listeners/FlyLogoutListener.java | 1 - src/main/resources/addon.yml | 2 +- src/main/resources/config.yml | 3 ++ src/main/resources/locales/en-US.yml | 1 + .../islandfly/listeners/FlyListenerTest.java | 14 +++---- 13 files changed, 124 insertions(+), 53 deletions(-) diff --git a/pom.xml b/pom.xml index 047525d..f19ba5c 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,8 @@ 1.20.4-R0.1-SNAPSHOT 2.0.0-SNAPSHOT + + 2.9.0 ${build.version}-SNAPSHOT @@ -123,6 +125,12 @@ ${bentobox.version} provided + + world.bentobox + level + ${level.version} + provided + org.mockito diff --git a/src/main/java/world/bentobox/islandfly/FlyToggleCommand.java b/src/main/java/world/bentobox/islandfly/FlyToggleCommand.java index 87f12a9..4d14698 100644 --- a/src/main/java/world/bentobox/islandfly/FlyToggleCommand.java +++ b/src/main/java/world/bentobox/islandfly/FlyToggleCommand.java @@ -1,15 +1,15 @@ package world.bentobox.islandfly; -import java.util.List; - import org.bukkit.entity.Player; - 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.util.Util; import world.bentobox.islandfly.config.Settings; +import java.util.List; + /** * This command allows to enable and disable fly mode. @@ -17,7 +17,8 @@ public class FlyToggleCommand extends CompositeCommand { - private Settings settings; + private final Settings settings; + private final IslandFlyAddon islandFlyAddon; /** * Default constructor @@ -26,6 +27,7 @@ public class FlyToggleCommand extends CompositeCommand { public FlyToggleCommand(CompositeCommand parent, IslandFlyAddon addon) { super(parent, "fly"); this.settings = addon.getSettings(); + this.islandFlyAddon = addon; } @@ -71,6 +73,12 @@ public boolean canExecute(User user, String label, List args) { } + if(islandFlyAddon.getSettings().getFlyMinLevel() > 1 && islandFlyAddon.getLevelAddon() != null) { + if (islandFlyAddon.getLevelAddon().getIslandLevel(island.getWorld(), island.getOwner()) < islandFlyAddon.getSettings().getFlyMinLevel()) { + user.sendMessage("islandfly.fly-min-level-alert", TextVariables.NUMBER, String.valueOf(islandFlyAddon.getSettings().getFlyMinLevel())); + return false; + } + } return true; } diff --git a/src/main/java/world/bentobox/islandfly/IslandFlyAddon.java b/src/main/java/world/bentobox/islandfly/IslandFlyAddon.java index 1cb5da6..9cedb82 100644 --- a/src/main/java/world/bentobox/islandfly/IslandFlyAddon.java +++ b/src/main/java/world/bentobox/islandfly/IslandFlyAddon.java @@ -1,17 +1,13 @@ package world.bentobox.islandfly; import org.bukkit.Material; - import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.configuration.Config; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.islandfly.config.Settings; -import world.bentobox.islandfly.listeners.FlyDeathListener; -import world.bentobox.islandfly.listeners.FlyFlagListener; -import world.bentobox.islandfly.listeners.FlyListener; -import world.bentobox.islandfly.listeners.FlyLoginListener; -import world.bentobox.islandfly.listeners.FlyLogoutListener; +import world.bentobox.islandfly.listeners.*; +import world.bentobox.level.Level; /** @@ -23,6 +19,11 @@ public class IslandFlyAddon extends Addon { */ private Settings settings; + /** + * Level addon instance. + */ + private Level levelAddon; + /** * A flag to allow or disallow flight on island * based on player's rank @@ -115,6 +116,21 @@ public void onDisable() { //Nothing to do here } + /** + * Check addon hooks. + */ + public void allLoaded() + { + // Try to find Level addon and if it does not exist, display a warning + this.getAddonByName("Level").ifPresentOrElse(addon -> + { + this.levelAddon = (Level) addon; + this.log("Level Addon hooked into Level addon."); + }, () -> + { + this.levelAddon = null; + }); + } /** * This method loads addon configuration settings in memory. @@ -136,4 +152,15 @@ private void loadSettings() { public Settings getSettings() { return settings; } + + + /** + * Gets level addon. + * + * @return the level addon + */ + public Level getLevelAddon() + { + return levelAddon; + } } diff --git a/src/main/java/world/bentobox/islandfly/config/Settings.java b/src/main/java/world/bentobox/islandfly/config/Settings.java index fe3bdb7..93f3274 100644 --- a/src/main/java/world/bentobox/islandfly/config/Settings.java +++ b/src/main/java/world/bentobox/islandfly/config/Settings.java @@ -7,14 +7,14 @@ package world.bentobox.islandfly.config; -import java.util.HashSet; -import java.util.Set; - import world.bentobox.bentobox.api.configuration.ConfigComment; import world.bentobox.bentobox.api.configuration.ConfigEntry; import world.bentobox.bentobox.api.configuration.ConfigObject; import world.bentobox.bentobox.api.configuration.StoreAt; +import java.util.HashSet; +import java.util.Set; + /** * Settings that implements ConfigObject is powerful and dynamic Config Objects that @@ -45,6 +45,13 @@ public int getFlyTimeout() return flyTimeout; } + public long getFlyMinLevel() { + return flyMinLevel; + } + + public void setFlyMinLevel(long flyMinLevel) { + this.flyMinLevel = flyMinLevel; + } /** * Method Settings#setFlyTimeout sets new value for the flyTimeout of this object. @@ -79,6 +86,7 @@ public void setFlyDisableOnLogout(boolean flyDisableOnLogout) } + /** * This method returns the disabledGameModes value. * @@ -115,8 +123,8 @@ public boolean isAllowCommandOutsideProtectionRange() /** - * Method Settings#setFlyDisableOnLogout sets new value for the flyDisableOnLogout of this object. - * @param flyDisableOnLogout new value for this object. + * Method Settings#setAllowCommandOutsideProtectionRange sets new value for the commandAllowed of this object. + * @param commandAllowed new value for this object. * */ public void setAllowCommandOutsideProtectionRange(boolean commandAllowed) @@ -142,6 +150,11 @@ public void setAllowCommandOutsideProtectionRange(boolean commandAllowed) @ConfigEntry(path = "logout-disable-fly") private boolean flyDisableOnLogout = false; + @ConfigComment("") + @ConfigComment("Minimum required level to toggle fly.") + @ConfigEntry(path = "fly-min-level") + private long flyMinLevel = 0; + @ConfigComment("") @ConfigComment("This list stores GameModes in which islandFly addon should not work.") @ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:") diff --git a/src/main/java/world/bentobox/islandfly/listeners/FlyDeathListener.java b/src/main/java/world/bentobox/islandfly/listeners/FlyDeathListener.java index eb42055..53fed96 100644 --- a/src/main/java/world/bentobox/islandfly/listeners/FlyDeathListener.java +++ b/src/main/java/world/bentobox/islandfly/listeners/FlyDeathListener.java @@ -1,20 +1,19 @@ package world.bentobox.islandfly.listeners; -import java.util.Optional; -import java.util.UUID; - import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerRespawnEvent; - import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.islandfly.IslandFlyAddon; +import java.util.Optional; +import java.util.UUID; + /** * This class manages Death and Respawn options. diff --git a/src/main/java/world/bentobox/islandfly/listeners/FlyFlagListener.java b/src/main/java/world/bentobox/islandfly/listeners/FlyFlagListener.java index a716cb1..69643b7 100644 --- a/src/main/java/world/bentobox/islandfly/listeners/FlyFlagListener.java +++ b/src/main/java/world/bentobox/islandfly/listeners/FlyFlagListener.java @@ -4,7 +4,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; - import world.bentobox.bentobox.api.events.flags.FlagProtectionChangeEvent; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; diff --git a/src/main/java/world/bentobox/islandfly/listeners/FlyListener.java b/src/main/java/world/bentobox/islandfly/listeners/FlyListener.java index 1719b6a..82c77ec 100644 --- a/src/main/java/world/bentobox/islandfly/listeners/FlyListener.java +++ b/src/main/java/world/bentobox/islandfly/listeners/FlyListener.java @@ -7,7 +7,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerToggleFlightEvent; - import world.bentobox.bentobox.api.events.island.IslandEnterEvent; import world.bentobox.bentobox.api.events.island.IslandExitEvent; import world.bentobox.bentobox.api.localization.TextVariables; @@ -23,15 +22,15 @@ public class FlyListener implements Listener { /** * Addon instance object. */ - private final IslandFlyAddon addon; + private final IslandFlyAddon islandFlyAddon; /** * Default constructor. - * @param addon instance of IslandFlyAddon + * @param islandFlyAddon instance of IslandFlyAddon */ - public FlyListener(final IslandFlyAddon addon) { - this.addon = addon; + public FlyListener(final IslandFlyAddon islandFlyAddon) { + this.islandFlyAddon = islandFlyAddon; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @@ -47,7 +46,7 @@ public void onToggleFlight(final PlayerToggleFlightEvent event) { * @return true if fly was blocked */ private boolean checkUser(User user) { - String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(user.getWorld()); + String permPrefix = islandFlyAddon.getPlugin().getIWM().getPermissionPrefix(user.getWorld()); // Ignore ops if (user.isOp() || user.getPlayer().getGameMode().equals(GameMode.CREATIVE) || user.getPlayer().getGameMode().equals(GameMode.SPECTATOR) @@ -59,7 +58,7 @@ private boolean checkUser(User user) { public void onEnterIsland(final IslandEnterEvent event) { final User user = User.getInstance(event.getPlayerUUID()); // Wait until after arriving at the island - Bukkit.getScheduler().runTask(this.addon.getPlugin(), () -> checkUser(user)); + Bukkit.getScheduler().runTask(this.islandFlyAddon.getPlugin(), () -> checkUser(user)); } /** @@ -70,7 +69,7 @@ public void onEnterIsland(final IslandEnterEvent event) { public void onExitIsland(final IslandExitEvent event) { final User user = User.getInstance(event.getPlayerUUID()); - String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(user.getWorld()); + String permPrefix = islandFlyAddon.getPlugin().getIWM().getPermissionPrefix(user.getWorld()); // Ignore ops if (user.isOp() || user.getPlayer().getGameMode().equals(GameMode.CREATIVE) || user.getPlayer().getGameMode().equals(GameMode.SPECTATOR) @@ -78,7 +77,7 @@ public void onExitIsland(final IslandExitEvent event) { || (!user.hasPermission(permPrefix + "island.fly") && !user.hasPermission(permPrefix + "island.flyspawn"))) return; // Alert player fly will be disabled - final int flyTimeout = this.addon.getSettings().getFlyTimeout(); + final int flyTimeout = this.islandFlyAddon.getSettings().getFlyTimeout(); // If timeout is 0 or less disable fly immediately if (flyTimeout <= 0) { @@ -91,7 +90,7 @@ public void onExitIsland(final IslandExitEvent event) { user.sendMessage("islandfly.fly-outside-alert", TextVariables.NUMBER, String.valueOf(flyTimeout)); } - Bukkit.getScheduler().runTaskLater(this.addon.getPlugin(), () -> removeFly(user), 20L* flyTimeout); + Bukkit.getScheduler().runTaskLater(this.islandFlyAddon.getPlugin(), () -> removeFly(user), 20L* flyTimeout); } @@ -104,16 +103,16 @@ boolean removeFly(User user) { // Verify player is still online if (!user.isOnline()) return false; - Island is = addon.getIslands().getProtectedIslandAt(user.getLocation()).orElse(null); + Island island = islandFlyAddon.getIslands().getProtectedIslandAt(user.getLocation()).orElse(null); - if (is == null) { + if (island == null) { disableFly(user); return true; } // Check if player is back on a spawn island - if (is.isSpawn()) { - if (this.addon.getPlugin().getIWM().getAddon(user.getWorld()) + if (island.isSpawn()) { + if (this.islandFlyAddon.getPlugin().getIWM().getAddon(user.getWorld()) .map(a -> !user.hasPermission(a.getPermissionPrefix() + "island.flyspawn")).orElse(false)) { disableFly(user); @@ -122,8 +121,15 @@ boolean removeFly(User user) { return false; } + if(islandFlyAddon.getSettings().getFlyMinLevel() > 1 && islandFlyAddon.getLevelAddon() != null) { + if (islandFlyAddon.getLevelAddon().getIslandLevel(island.getWorld(), island.getOwner()) < islandFlyAddon.getSettings().getFlyMinLevel()) { + disableFly(user); + return false; + } + } + // Check if player is allowed to fly on the island he is at that moment - if (!is.isAllowed(user, IslandFlyAddon.ISLAND_FLY_PROTECTION)) { + if (!island.isAllowed(user, IslandFlyAddon.ISLAND_FLY_PROTECTION)) { disableFly(user); return true; } diff --git a/src/main/java/world/bentobox/islandfly/listeners/FlyLoginListener.java b/src/main/java/world/bentobox/islandfly/listeners/FlyLoginListener.java index 9a87cf4..5644f4b 100644 --- a/src/main/java/world/bentobox/islandfly/listeners/FlyLoginListener.java +++ b/src/main/java/world/bentobox/islandfly/listeners/FlyLoginListener.java @@ -7,7 +7,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; - +import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.islandfly.IslandFlyAddon; @@ -19,16 +19,16 @@ public class FlyLoginListener implements Listener { /** * IslandFlyAddon instance. */ - private final IslandFlyAddon addon; + private final IslandFlyAddon islandFlyAddon; /** * Default constructor. - * @param addon instance of IslandFlyAddon + * @param islandFlyAddon instance of IslandFlyAddon */ - public FlyLoginListener(IslandFlyAddon addon) + public FlyLoginListener(IslandFlyAddon islandFlyAddon) { - this.addon = addon; + this.islandFlyAddon = islandFlyAddon; } @@ -40,12 +40,20 @@ public FlyLoginListener(IslandFlyAddon addon) public void onLogin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); final User user = User.getInstance(player); - final String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(player.getWorld()); + final String permPrefix = islandFlyAddon.getPlugin().getIWM().getPermissionPrefix(player.getWorld()); if (player.hasPermission(permPrefix + "island.fly") - && !this.addon.getSettings().isFlyDisableOnLogout() + && !this.islandFlyAddon.getSettings().isFlyDisableOnLogout() && isInAir(player) - && addon.getIslands().userIsOnIsland(user.getWorld(), user) - && !addon.getIslands().getIslandAt(user.getLocation()).map(i -> { + && islandFlyAddon.getIslands().userIsOnIsland(user.getWorld(), user) + && !islandFlyAddon.getIslands().getIslandAt(user.getLocation()).map(i -> { + + if(islandFlyAddon.getSettings().getFlyMinLevel() > 1 && islandFlyAddon.getLevelAddon() != null) { + if (islandFlyAddon.getLevelAddon().getIslandLevel(i.getWorld(), i.getOwner()) < islandFlyAddon.getSettings().getFlyMinLevel()) { + user.sendMessage("islandfly.fly-min-level-alert", TextVariables.NUMBER, String.valueOf(islandFlyAddon.getSettings().getFlyMinLevel())); + return false; + } + } + if (i.isAllowed(user, IslandFlyAddon.ISLAND_FLY_PROTECTION)) { // Enable fly player.setFallDistance(0); diff --git a/src/main/java/world/bentobox/islandfly/listeners/FlyLogoutListener.java b/src/main/java/world/bentobox/islandfly/listeners/FlyLogoutListener.java index c0b6367..dd1d3b0 100644 --- a/src/main/java/world/bentobox/islandfly/listeners/FlyLogoutListener.java +++ b/src/main/java/world/bentobox/islandfly/listeners/FlyLogoutListener.java @@ -5,7 +5,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; - import world.bentobox.islandfly.IslandFlyAddon; diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index 9eeb04c..d3bdc78 100644 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -4,7 +4,7 @@ main: world.bentobox.islandfly.IslandFlyAddon icon: FEATHER api-version: 1.15.4 -softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock +softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, Level authors: [DarkRails, tastybento] diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b47346b..3daedb6 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,9 @@ fly-timeout: 5 # # This allows to change if players should lose their fly mode if they quit server. logout-disable-fly: false +# +# Minimum required level to toggle fly. +fly-min-level: 0 # # This list stores GameModes in which islandFly addon should not work. # To disable addon it is necessary to write its name in new line that starts with -. Example: diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 2241baf..789606f 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -1,5 +1,6 @@ islandfly: fly-outside-alert: "&c You are outside your island so fly mode will be disabled in &e[number] &c seconds." + fly-min-level-alert: "&c You can only enable fly once your Island level reaches &e[number]&c!" fly-turning-off-alert: "&c You are not permitted to fly here anymore. Turning fly off in &e[number] &c seconds." disable-fly: "&c Your fly mode has been disabled." not-allowed: "&c Flying is not allowed here." diff --git a/src/test/java/world/bentobox/islandfly/listeners/FlyListenerTest.java b/src/test/java/world/bentobox/islandfly/listeners/FlyListenerTest.java index d4685ab..849d910 100644 --- a/src/test/java/world/bentobox/islandfly/listeners/FlyListenerTest.java +++ b/src/test/java/world/bentobox/islandfly/listeners/FlyListenerTest.java @@ -144,7 +144,7 @@ public void tearDown() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandGraceTime() { @@ -157,7 +157,7 @@ public void testOnExitIslandGraceTime() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandGraceTimeOp() { @@ -171,7 +171,7 @@ public void testOnExitIslandGraceTimeOp() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandGraceTimePermission() { @@ -185,7 +185,7 @@ public void testOnExitIslandGraceTimePermission() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandGraceTimeNotFlying() { @@ -200,7 +200,7 @@ public void testOnExitIslandGraceTimeNotFlying() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandNoGraceTime() { @@ -214,7 +214,7 @@ public void testOnExitIslandNoGraceTime() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandNoGraceTimeNoPermission() { @@ -229,7 +229,7 @@ public void testOnExitIslandNoGraceTimeNoPermission() { } /** - * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandEvent.IslandExitEvent)}. + * Test method for {@link world.bentobox.islandfly.listeners.FlyListener#onExitIsland(world.bentobox.bentobox.api.events.island.IslandExitEvent)}. */ @Test public void testOnExitIslandNoGraceTimeCreativeOrSpectator() {