From f989d9614afadc0080cd4d6c6a7e84197b70be07 Mon Sep 17 00:00:00 2001 From: Ben Woo <30431861+benwoo1110@users.noreply.github.com> Date: Tue, 3 Aug 2021 20:01:47 +0800 Subject: [PATCH] Adds permission node to bypass fly enforcement (#2469) --- .../onarandombox/MultiverseCore/MVWorld.java | 13 ++-- .../listeners/MVPlayerListener.java | 66 ++++++++++--------- .../MultiverseCore/utils/MVPermissions.java | 11 ++++ .../MultiverseCore/utils/PermissionTools.java | 17 +++++ .../MultiverseCore/utils/WorldManager.java | 14 ++-- 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java index d7367ad2..831a4a39 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java @@ -337,7 +337,8 @@ public class MVWorld implements MultiverseWorld { private Permission permission; private Permission exempt; - private Permission ignoreperm; + private Permission ignoregamemodeperm; + private Permission ignoreflyperm; private Permission limitbypassperm; /** @@ -390,8 +391,10 @@ public class MVWorld implements MultiverseWorld { private void initPerms() { this.permission = new Permission("multiverse.access." + this.getName(), "Allows access to " + this.getName(), PermissionDefault.OP); // This guy is special. He shouldn't be added to any parent perms. - this.ignoreperm = new Permission("mv.bypass.gamemode." + this.getName(), + this.ignoregamemodeperm = new Permission("mv.bypass.gamemode." + this.getName(), "Allows players with this permission to ignore gamemode changes.", PermissionDefault.FALSE); + this.ignoreflyperm = new Permission("mv.bypass.fly." + this.getName(), + "Allows players with this permission to ignore fly changes.", PermissionDefault.FALSE); this.exempt = new Permission("multiverse.exempt." + this.getName(), "A player who has this does not pay to enter this world, or use any MV portals in it " + this.getName(), PermissionDefault.OP); @@ -401,13 +404,15 @@ public class MVWorld implements MultiverseWorld { try { this.plugin.getServer().getPluginManager().addPermission(this.permission); this.plugin.getServer().getPluginManager().addPermission(this.exempt); - this.plugin.getServer().getPluginManager().addPermission(this.ignoreperm); + this.plugin.getServer().getPluginManager().addPermission(this.ignoregamemodeperm); + this.plugin.getServer().getPluginManager().addPermission(this.ignoreflyperm); this.plugin.getServer().getPluginManager().addPermission(this.limitbypassperm); // Add the permission and exempt to parents. this.addToUpperLists(this.permission); // Add ignore to it's parent: - this.ignoreperm.addParent("mv.bypass.gamemode.*", true); + this.ignoregamemodeperm.addParent("mv.bypass.gamemode.*", true); + this.ignoreflyperm.addParent("mv.bypass.fly.*", true); // Add limit bypass to it's parent this.limitbypassperm.addParent("mv.bypass.playerlimit.*", true); } catch (IllegalArgumentException e) { diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java index 2921f9c5..63c285ef 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java @@ -349,36 +349,42 @@ public class MVPlayerListener implements Listener { // We perform this task one tick later to MAKE SURE that the player actually reaches the // destination world, otherwise we'd be changing the player mode if they havent moved anywhere. this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, - new Runnable() { - @Override - public void run() { - if (!MVPlayerListener.this.pt.playerCanIgnoreGameModeRestriction(world, player)) { - // Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled. - if (player.getWorld() == world.getCBWorld()) { - Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString()); - Logging.finest("From World: %s", player.getWorld()); - Logging.finest("To World: %s", world); - player.setGameMode(world.getGameMode()); - // Check if their flight mode should change - // TODO need a override permission for this - if (player.getAllowFlight() && !world.getAllowFlight() && player.getGameMode() != GameMode.CREATIVE) { - player.setAllowFlight(false); - if (player.isFlying()) { - player.setFlying(false); - } - } else if (world.getAllowFlight()) { - if (player.getGameMode() == GameMode.CREATIVE) { - player.setAllowFlight(true); - } - } - } else { - Logging.fine("The gamemode/allowfly was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'", - player.getName(), player.getWorld().getName(), world.getName()); - } - } else { - Logging.fine("Player: " + player.getName() + " is IMMUNE to gamemode changes!"); - } + new Runnable() { + @Override + public void run() { + if (player.getWorld() != world.getCBWorld()) { + Logging.fine("The gamemode was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'", + player.getName(), player.getWorld().getName(), world.getName()); + return; } - }, 1L); + + boolean isAllowFlight = player.getAllowFlight(); + boolean isFlying = player.isFlying(); + + if (!MVPlayerListener.this.pt.playerCanIgnoreGameModeRestriction(world, player)) { + // Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled. + Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString()); + Logging.finest("From World: %s", player.getWorld()); + Logging.finest("To World: %s", world); + player.setGameMode(world.getGameMode()); + } else { + Logging.fine("Player: " + player.getName() + " is IMMUNE to gamemode changes!"); + } + + if (!MVPlayerListener.this.pt.playerCanIgnoreFlyRestriction(world, player)) { + if (player.getGameMode() == GameMode.CREATIVE && world.getAllowFlight()) { + player.setAllowFlight(true); + } else if (isAllowFlight && player.getGameMode() != GameMode.SPECTATOR) { + player.setAllowFlight(false); + player.setFlying(false); + } + } else { + // Set back to previous state before gamemode change + player.setAllowFlight(isAllowFlight); + player.setFlying(isFlying); + Logging.fine("Player: " + player.getName() + " is IMMUNE to fly changes!"); + } + } + }, 1L); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/MVPermissions.java b/src/main/java/com/onarandombox/MultiverseCore/utils/MVPermissions.java index 24ca8692..8dff0f96 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/MVPermissions.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/MVPermissions.java @@ -48,6 +48,17 @@ public class MVPermissions implements PermissionsInterface { return p.hasPermission("mv.bypass.gamemode." + w.getName()); } + /** + * Check if a Player can ignore Fly restrictions for world they travel to. + * + * @param p The {@link Player} to check. + * @param w The {@link MultiverseWorld} the player wants to teleport to. + * @return True if they should bypass restrictions. + */ + public boolean canIgnoreFlyRestriction(Player p, MultiverseWorld w) { + return p.hasPermission("mv.bypass.fly." + w.getName()); + } + /** * Check if a Player can teleport to the Destination world from there current world. * diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java index ef5e08c4..17afe66f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java @@ -300,4 +300,21 @@ public class PermissionTools { return true; } } + + /** + * Checks to see if a player should bypass fly restrictions. + * + * @param toWorld world travelling to. + * @param teleportee player travelling. + * @return True if they should bypass restrictions + */ + public boolean playerCanIgnoreFlyRestriction(MultiverseWorld toWorld, Player teleportee) { + if (toWorld != null) { + return this.plugin.getMVPerms().canIgnoreFlyRestriction(teleportee, toWorld); + } else { + // TODO: Determine if this value is false because a world didn't exist + // or if it was because a world wasn't imported. + return true; + } + } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java index 0b2ab070..c48361b5 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java @@ -753,6 +753,7 @@ public class WorldManager implements MVWorldManager { this.plugin.getServer().getPluginManager().removePermission(w.getExemptPermission().getName()); // Special namespace for gamemodes this.plugin.getServer().getPluginManager().removePermission("mv.bypass.gamemode." + w.getName()); + this.plugin.getServer().getPluginManager().removePermission("mv.bypass.fly." + w.getName()); } // Recalc the all permission this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allAccess); @@ -777,10 +778,15 @@ public class WorldManager implements MVWorldManager { } private void ensureSecondNamespaceIsPrepared() { - Permission special = this.plugin.getServer().getPluginManager().getPermission("mv.bypass.gamemode.*"); - if (special == null) { - special = new Permission("mv.bypass.gamemode.*", PermissionDefault.FALSE); - this.plugin.getServer().getPluginManager().addPermission(special); + Permission specialGameMode = this.plugin.getServer().getPluginManager().getPermission("mv.bypass.gamemode.*"); + Permission specialFly = this.plugin.getServer().getPluginManager().getPermission("mv.bypass.fly.*"); + if (specialGameMode == null) { + specialGameMode = new Permission("mv.bypass.gamemode.*", PermissionDefault.FALSE); + this.plugin.getServer().getPluginManager().addPermission(specialGameMode); + } + if (specialFly == null) { + specialFly = new Permission("mv.bypass.fly.*", PermissionDefault.FALSE); + this.plugin.getServer().getPluginManager().addPermission(specialFly); } }