Adds permission node to bypass fly enforcement (#2469)

This commit is contained in:
Ben Woo 2021-08-03 20:01:47 +08:00 committed by GitHub
parent 1a8a97daf1
commit f989d9614a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 38 deletions

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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.
*

View File

@ -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;
}
}
}

View File

@ -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);
}
}