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.
This commit is contained in:
Kristian Knarvik 2021-10-18 03:35:59 +02:00
parent fabe0dda80
commit d9ae5456cc

View File

@ -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 <p>The vehicle passing through</p>
*/
private static void teleportVehicle(List<Entity> 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<Entity> 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 <p>All passengers in the teleporting vehicle</p>
* @param entrancePortal <p>The portal the vehicle is entering from</p>
* @param cost <p>The cost each player has to pay</p>
* @return <p>True if all player passengers paid successfully</p>
*/
private static boolean takePlayerPayment(List<Entity> 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 <p>The player trying to teleport</p>
* @param entrancePortal <p>The portal the player is entering</p>
* @param destinationPortal <p>The portal the player is to exit from</p>
* @return <p>True if the player is allowed to teleport and is able to pay necessary fees</p>
*/
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);
}
}