package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.portal.PlayerTeleporter; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalOption; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; /** * Helper class for deciding which actions a player is allowed to perform */ public final class PermissionHelper { private PermissionHelper() { } /** * Opens a portal if the given player is allowed to, and if the portal is not already open * * @param player

The player opening the portal

* @param portal

The portal to open

*/ public static void openPortal(Player player, Portal portal) { Portal destination = portal.getPortalActivator().getDestination(); //For an always open portal, no action is necessary if (portal.getOptions().isAlwaysOn() || portal.getOptions().isRandom() || portal.getOptions().isBungee()) { return; } //Destination is invalid or the same portal. Send an error message if (destination == null || destination == portal) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); return; } //Portal is already open if (portal.isOpen()) { //Close the portal if this player opened the portal if (portal.getActivePlayer() == player) { portal.getPortalOpener().closePortal(false); } return; } //Deny access if another player has activated the portal, and it's still in use if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && portal.getActivePlayer() != player) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //Check if the player can use the private gate if (portal.getOptions().isPrivate() && !PermissionHelper.canUsePrivatePortal(player, portal)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); return; } //Destination is currently in use by another player, blocking teleportation if (destination.isOpen() && !destination.getOptions().isAlwaysOn()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); return; } //Open the portal portal.getPortalOpener().openPortal(player, false); } /** * Creates a StargateAccessEvent and gets the updated deny value * *

The event is used for other plugins to bypass the permission checks.

* * @param player

The player trying to use the portal

* @param portal

The portal the player is trying to use

* @param deny

Whether the player's access has already been denied by a previous check

* @return

False if the player should be allowed through the portal

*/ public static boolean portalAccessDenied(Player player, Portal portal, boolean deny) { StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); Stargate.server.getPluginManager().callEvent(event); return event.getDeny(); } /** * Checks whether a given user cannot travel between two portals * * @param player

The player to check

* @param entrancePortal

The portal the user wants to enter

* @param destination

The portal the user wants to exit from

* @return

False if the user is allowed to access the portal

*/ public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { boolean deny = false; if (entrancePortal.getOptions().isBungee()) { if (!PermissionHelper.canAccessServer(player, entrancePortal.getNetwork())) { //If the portal is a bungee portal, and the player cannot access the server, deny Stargate.debug("cannotAccessPortal", "Cannot access server"); deny = true; } } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getNetwork())) { //If the player does not have access to the network, deny Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; } else if (PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { //If the player does not have access to the portal's world, deny Stargate.debug("cannotAccessPortal", "Cannot access world"); deny = true; } //Allow other plugins to override whether the player can access the portal return portalAccessDenied(player, entrancePortal, deny); } /** * Checks whether a player has the given permission * *

This is the same as player.hasPermission(), but this function allows for printing permission debugging info.

* * @param player

The player to check

* @param permission

The permission to check

* @return

True if the player has the permission

*/ public static boolean hasPermission(Player player, String permission) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPerm::Permission(" + player.getName() + ")", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); } /** * Check if a player has been given a permission implicitly * *

This should be run if a player has a parent permission to check for the child permission. It is assumed the * player has the child permission unless it's explicitly set to false.

* * @param player

The player to check

* @param permission

The permission to check

* @return

True if the player has the permission implicitly or explicitly

*/ public static boolean hasPermissionImplicit(Player player, String permission) { if (!player.isPermissionSet(permission)) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPermissionImplicit::Permission", permission + " => implicitly true"); } return true; } if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPermissionImplicit::Permission", permission + " => " + player.hasPermission(permission)); } return player.hasPermission(permission); } /** * Checks whether a player can access the given world * * @param player

The player trying to access the world

* @param world

The world the player is trying to access

* @return

False if the player should be allowed to access the world

*/ public static boolean cannotAccessWorld(Player player, String world) { //The player can access all worlds if (hasPermission(player, "stargate.world")) { //Check if the world permission has been explicitly denied return !hasPermissionImplicit(player, "stargate.world." + world); } //The player can access the destination world return !hasPermission(player, "stargate.world." + world); } /** * Checks whether a player can access the given network * * @param player

The player to check

* @param network

The network to check

* @return

True if the player is denied from accessing the network

*/ public static boolean cannotAccessNetwork(Player player, String network) { //The player can access all networks if (hasPermission(player, "stargate.network")) { //Check if the world permission has been explicitly denied return !hasPermissionImplicit(player, "stargate.network." + network); } //Check if the player can access this network if (hasPermission(player, "stargate.network." + network)) { return false; } //Is able to create personal gates (Assumption is made they can also access them) String playerName = player.getName(); if (playerName.length() > 11) { playerName = playerName.substring(0, 11); } return !network.equals(playerName) || !hasPermission(player, "stargate.create.personal"); } /** * Checks whether a player can access the given bungee server * * @param player

The player trying to teleport

* @param server

The server the player is trying to connect to

* @return

True if the player is allowed to access the given server

*/ public static boolean canAccessServer(Player player, String server) { //The player can access all servers if (hasPermission(player, "stargate.server")) { //Check if the server permission has been explicitly denied return hasPermissionImplicit(player, "stargate.server." + server); } //The player can access the destination server return hasPermission(player, "stargate.server." + server); } /** * Checks whether the given player can teleport the given stretch for free * * @param player

The player trying to teleport

* @param src

The portal the player is entering

* @param dest

The portal the player wants to teleport to

* @return

True if the player can travel for free

*/ public static boolean isFree(Player player, Portal src, Portal dest) { //This portal is free if (src.getOptions().isFree()) { return true; } //Player can use this portal for free if (hasPermission(player, "stargate.free.use")) { return true; } //Don't charge for free destinations unless specified in the config return dest != null && !Stargate.getEconomyConfig().chargeFreeDestination() && dest.getOptions().isFree(); } /** * Checks whether the player can see this gate (Hidden property check) * *

This decides if the player can see the gate on the network selection screen

* * @param player

The player to check

* @param portal

The portal to check

* @return

True if the given player can see the given portal

*/ public static boolean canSeePortal(Player player, Portal portal) { //The portal is not hidden if (!portal.getOptions().isHidden()) { return true; } //The player can see all hidden portals if (hasPermission(player, "stargate.admin.hidden")) { return true; } //The player is the owner of the portal return portal.isOwner(player); } /** * Checks if the given player is allowed to use the given private portal * * @param player

The player trying to use the portal

* @param portal

The private portal used

* @return

True if the player is allowed to use the portal

*/ public static boolean canUsePrivatePortal(Player player, Portal portal) { //Check if the player is the owner of the gate if (portal.isOwner(player)) { return true; } //The player is an admin with the ability to use private gates return hasPermission(player, "stargate.admin.private"); } /** * Checks if the given player has access to the given portal option * * @param player

The player trying to use the option

* @param option

The option the player is trying to use

* @return

True if the player is allowed to create a portal with the given option

*/ public static boolean canUseOption(Player player, PortalOption option) { return hasPermission(player, option.getPermissionString()); } /** * Checks if the given player is allowed to create gates on the given network * * @param player

The player trying to create a new gate

* @param network

The network the player is trying to create a gate on

* @return

True if the player is allowed to create the new gate

*/ public static boolean canCreateNetworkGate(Player player, String network) { //Check if the player is allowed to create a portal on any network if (hasPermission(player, "stargate.create.network")) { //Check if the network has been explicitly denied return hasPermissionImplicit(player, "stargate.create.network." + network); } //Check if the player is allowed to create on this specific network return hasPermission(player, "stargate.create.network." + network); } /** * Checks whether the given player is allowed to create a personal gate * * @param player

The player trying to create the new gate

* @return

True if the player is allowed

*/ public static boolean canCreatePersonalPortal(Player player) { return hasPermission(player, "stargate.create.personal"); } /** * Checks if the given player can create a portal with the given gate layout * * @param player

The player trying to create a portal

* @param gate

The gate type of the new portal

* @return

True if the player is allowed to create a portal with the given gate layout

*/ public static boolean canCreatePortal(Player player, String gate) { //Check if the player is allowed to create all gates if (hasPermission(player, "stargate.create.gate")) { //Check if the gate type has been explicitly denied return hasPermissionImplicit(player, "stargate.create.gate." + gate); } //Check if the player can create the specific gate type return hasPermission(player, "stargate.create.gate." + gate); } /** * Checks if the given player can destroy the given portal * * @param player

The player trying to destroy the portal

* @param portal

The portal to destroy

* @return

True if the player is allowed to destroy the portal

*/ public static boolean canDestroyPortal(Player player, Portal portal) { String network = portal.getNetwork(); //Use a special check for bungee portals if (portal.getOptions().isBungee()) { return hasPermission(player, "stargate.admin.bungee"); } //Check if the player is allowed to destroy on all networks if (hasPermission(player, "stargate.destroy.network")) { //Check if the network has been explicitly denied return hasPermissionImplicit(player, "stargate.destroy.network." + network); } //Check if the player is allowed to destroy on the network if (hasPermission(player, "stargate.destroy.network." + network)) { return true; } //Check if personal portal and if the player is allowed to destroy it return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal"); } /** * Decide of the player can teleport through a portal * * @param entrancePortal

The portal the player is entering from

* @param destination

The destination of the portal the player is inside

* @param player

The player wanting to teleport

* @param event

The move event causing the teleportation

* @return

True if the player cannot teleport. False otherwise

*/ public static boolean playerCannotTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { //No portal or not open if (entrancePortal == null || !entrancePortal.isOpen()) { return true; } //Not open for this player if (!entrancePortal.getPortalOpener().isOpenFor(player)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); return true; } //No destination if (!entrancePortal.getOptions().isBungee() && destination == null) { return true; } //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); new PlayerTeleporter(entrancePortal, player).teleport(entrancePortal, event); entrancePortal.getPortalOpener().closePortal(false); return true; } //Player cannot pay for teleportation int cost = Stargate.getEconomyConfig().getUseCost(player, entrancePortal, destination); if (cost > 0) { return EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost); } return false; } }