From d9ae5456ccdbde05736d7892aafb5ee9dd46c8f4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 18 Oct 2021 03:35:59 +0200 Subject: [PATCH] Improves permission checking for vehicles with multiple passengers Changes some log messages into debug messages Makes sure that all player passengers of a vehicle have their permissions verified and fee paid. This ensures passengers won't get a free ride, or be allowed to access restricted areas by playing stowaway. --- .../listener/VehicleEventListener.java | 73 +++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 57d3ad4..6eb1002 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; +import net.knarcraft.stargate.portal.PortalTeleporter; import net.knarcraft.stargate.utility.EconomyHandler; import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EntityHelper; @@ -59,19 +60,22 @@ public class VehicleEventListener implements Listener { * @param vehicle

The vehicle passing through

*/ private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { + String route = "VehicleEventListener::teleportVehicle"; + String prefix = Stargate.getString("prefix"); + if (!passengers.isEmpty() && passengers.get(0) instanceof Player) { - Stargate.logger.info(Stargate.getString("prefix") + "Found passenger vehicle"); + Stargate.debug(route, prefix + "Found passenger vehicle"); teleportPlayerAndVehicle(entrancePortal, vehicle, passengers); } else { - Stargate.logger.info(Stargate.getString("prefix") + "Found empty vehicle"); + Stargate.debug(route, prefix + "Found empty vehicle"); Portal destinationPortal = entrancePortal.getDestination(); if (destinationPortal == null) { - Stargate.logger.warning(Stargate.getString("prefix") + "Unable to find portal destination"); + Stargate.debug(route, prefix + "Unable to find portal destination"); return; } Stargate.debug("vehicleTeleport", destinationPortal.getWorld() + " " + destinationPortal.getSignLocation()); - destinationPortal.teleport(vehicle, entrancePortal); + new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); } } @@ -84,34 +88,77 @@ public class VehicleEventListener implements Listener { */ private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle, List passengers) { Player player = (Player) passengers.get(0); + //On the assumption that a non-player cannot sit in the driver's seat and since some portals can only be open + // to one player at a time, we only need to check if the portal is open to the driver. if (!entrancePortal.isOpenFor(player)) { Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); return; } + //If no destination exists, the teleportation cannot happen Portal destinationPortal = entrancePortal.getDestination(player); if (destinationPortal == null) { return; } - //Make sure the user can access the portal - if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { - Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); - entrancePortal.close(false); - return; + //Make sure all player passengers are allowed to, and can afford to, enter the portal + for (Entity entity : passengers) { + if (entity instanceof Player && !playerCanTeleport((Player) entity, entrancePortal, destinationPortal)) { + return; + } } - //Transfer payment if necessary - int cost = EconomyHandler.getDefaultUseCost(player, entrancePortal, destinationPortal); + //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be + // run after it has been confirmed that all passengers are able to pay + int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); if (cost > 0) { - if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { + if (!takePlayerPayment(passengers, entrancePortal, cost)) { return; } } Stargate.sendSuccessMessage(player, Stargate.getString("teleportMsg")); - destinationPortal.teleport(vehicle, entrancePortal); + new PortalTeleporter(destinationPortal).teleport(vehicle, entrancePortal); entrancePortal.close(false); } + /** + * Takes payment from all player passengers + * + * @param passengers

All passengers in the teleporting vehicle

+ * @param entrancePortal

The portal the vehicle is entering from

+ * @param cost

The cost each player has to pay

+ * @return

True if all player passengers paid successfully

+ */ + private static boolean takePlayerPayment(List passengers, Portal entrancePortal, int cost) { + for (Entity entity : passengers) { + //If the passenger is a player, make it pay + if (entity instanceof Player && EconomyHelper.cannotPayTeleportFee(entrancePortal, (Player) entity, cost)) { + return false; + } + } + return true; + } + + /** + * Checks whether the given player is allowed to and can afford to teleport + * + * @param player

The player trying to teleport

+ * @param entrancePortal

The portal the player is entering

+ * @param destinationPortal

The portal the player is to exit from

+ * @return

True if the player is allowed to teleport and is able to pay necessary fees

+ */ + private static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { + //Make sure the user can access the portal + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { + Stargate.sendErrorMessage(player, Stargate.getString("denyMsg")); + entrancePortal.close(false); + return false; + } + + //Transfer payment if necessary + int cost = EconomyHandler.getUseCost(player, entrancePortal, destinationPortal); + return cost <= 0 || EconomyHandler.canAffordFee(player, cost); + } + }