Adds proper checking and odd case catching before teleporting players through artificial end portals
Adds a proper permission check to make sure players are allowed to teleport through the artificial portal Adds a teleportation back to the entrance as the teleportation event cannot be properly cancelled Adds a proper class for storing info about the teleportation
This commit is contained in:
parent
53cd55938b
commit
e14007380f
@ -0,0 +1,43 @@
|
|||||||
|
package net.knarcraft.stargate.container;
|
||||||
|
|
||||||
|
import net.knarcraft.stargate.portal.Portal;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a player teleporting from the end to the over-world using an artificial end portal
|
||||||
|
*/
|
||||||
|
public class FromTheEndTeleportation {
|
||||||
|
|
||||||
|
private final Player teleportingPlayer;
|
||||||
|
private final Portal exitPortal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new teleportation from the end
|
||||||
|
*
|
||||||
|
* @param teleportingPlayer <p>The teleporting player</p>
|
||||||
|
* @param exitPortal <p>The portal to exit from</p>
|
||||||
|
*/
|
||||||
|
public FromTheEndTeleportation(Player teleportingPlayer, Portal exitPortal) {
|
||||||
|
this.teleportingPlayer = teleportingPlayer;
|
||||||
|
this.exitPortal = exitPortal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the teleporting player
|
||||||
|
*
|
||||||
|
* @return <p>The teleporting player</p>
|
||||||
|
*/
|
||||||
|
public Player getPlayer() {
|
||||||
|
return this.teleportingPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the portal to exit from
|
||||||
|
*
|
||||||
|
* @return <p>The portal to exit from</p>
|
||||||
|
*/
|
||||||
|
public Portal getExit() {
|
||||||
|
return this.exitPortal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,8 +5,6 @@ import net.knarcraft.stargate.container.BlockLocation;
|
|||||||
import net.knarcraft.stargate.portal.Portal;
|
import net.knarcraft.stargate.portal.Portal;
|
||||||
import net.knarcraft.stargate.portal.PortalHandler;
|
import net.knarcraft.stargate.portal.PortalHandler;
|
||||||
import net.knarcraft.stargate.utility.BungeeHelper;
|
import net.knarcraft.stargate.utility.BungeeHelper;
|
||||||
import net.knarcraft.stargate.utility.EconomyHandler;
|
|
||||||
import net.knarcraft.stargate.utility.EconomyHelper;
|
|
||||||
import net.knarcraft.stargate.utility.MaterialHelper;
|
import net.knarcraft.stargate.utility.MaterialHelper;
|
||||||
import net.knarcraft.stargate.utility.PermissionHelper;
|
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
@ -127,7 +125,7 @@ public class PlayerEventListener implements Listener {
|
|||||||
Portal destination = entrancePortal.getDestination(player);
|
Portal destination = entrancePortal.getDestination(player);
|
||||||
|
|
||||||
//Decide if the anything stops the player from teleport
|
//Decide if the anything stops the player from teleport
|
||||||
if (!playerCanTeleport(entrancePortal, destination, player, event)) {
|
if (PermissionHelper.playerCannotTeleport(entrancePortal, destination, player, event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,47 +320,4 @@ public class PlayerEventListener implements Listener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Decide of the player can teleport through a portal
|
|
||||||
*
|
|
||||||
* @param entrancePortal <p>The portal the player is entering from</p>
|
|
||||||
* @param destination <p>The destination of the portal the player is inside</p>
|
|
||||||
* @param player <p>The player wanting to teleport</p>
|
|
||||||
* @param event <p>The move event causing the teleportation</p>
|
|
||||||
* @return <p>True if the player can teleport. False otherwise</p>
|
|
||||||
*/
|
|
||||||
private boolean playerCanTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) {
|
|
||||||
// No portal or not open
|
|
||||||
if (entrancePortal == null || !entrancePortal.isOpen()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not open for this player
|
|
||||||
if (!entrancePortal.isOpenFor(player)) {
|
|
||||||
Stargate.sendErrorMessage(player, Stargate.getString("denyMsg"));
|
|
||||||
entrancePortal.teleport(player, entrancePortal, event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//No destination
|
|
||||||
if (!entrancePortal.getOptions().isBungee() && destination == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Player cannot access portal
|
|
||||||
if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) {
|
|
||||||
Stargate.sendErrorMessage(player, Stargate.getString("denyMsg"));
|
|
||||||
entrancePortal.teleport(player, entrancePortal, event);
|
|
||||||
entrancePortal.close(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Player cannot pay for teleportation
|
|
||||||
int cost = EconomyHandler.getUseCost(player, entrancePortal, destination);
|
|
||||||
if (cost > 0) {
|
|
||||||
return EconomyHelper.payTeleportFee(entrancePortal, player, cost);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package net.knarcraft.stargate.listener;
|
package net.knarcraft.stargate.listener;
|
||||||
|
|
||||||
import net.knarcraft.stargate.container.TwoTuple;
|
import net.knarcraft.stargate.container.FromTheEndTeleportation;
|
||||||
import net.knarcraft.stargate.portal.Portal;
|
import net.knarcraft.stargate.portal.Portal;
|
||||||
import net.knarcraft.stargate.portal.PortalHandler;
|
import net.knarcraft.stargate.portal.PortalHandler;
|
||||||
|
import net.knarcraft.stargate.utility.PermissionHelper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -23,7 +24,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class PortalEventListener implements Listener {
|
public class PortalEventListener implements Listener {
|
||||||
|
|
||||||
private static final List<TwoTuple<Player, Portal>> playersFromTheEnd = new ArrayList<>();
|
private static final List<FromTheEndTeleportation> playersFromTheEnd = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen for and abort vanilla portal creation caused by stargate creation
|
* Listen for and abort vanilla portal creation caused by stargate creation
|
||||||
@ -55,12 +56,18 @@ public class PortalEventListener implements Listener {
|
|||||||
World world = location.getWorld();
|
World world = location.getWorld();
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
//Block normal portal teleportation if teleporting from a stargate
|
//Block normal portal teleportation if teleporting from a stargate
|
||||||
if (entity instanceof Player && location.getBlock().getType() == Material.END_PORTAL && world != null &&
|
if (entity instanceof Player player && location.getBlock().getType() == Material.END_PORTAL && world != null &&
|
||||||
world.getEnvironment() == World.Environment.THE_END) {
|
world.getEnvironment() == World.Environment.THE_END) {
|
||||||
Portal portal = PortalHandler.getByAdjacentEntrance(location);
|
Portal portal = PortalHandler.getByAdjacentEntrance(location);
|
||||||
if (portal != null) {
|
|
||||||
playersFromTheEnd.add(new TwoTuple<>((Player) entity, portal.getDestination()));
|
//Remove any old player teleportations in case weird things happen
|
||||||
|
playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player));
|
||||||
|
//Decide if the anything stops the player from teleporting
|
||||||
|
if (PermissionHelper.playerCannotTeleport(portal, portal.getDestination(), player, null)) {
|
||||||
|
//Teleport the player back to the portal they came in, just in case
|
||||||
|
playersFromTheEnd.add(new FromTheEndTeleportation(player, portal));
|
||||||
}
|
}
|
||||||
|
playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getDestination()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,14 +79,10 @@ public class PortalEventListener implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onRespawn(PlayerRespawnEvent event) {
|
public void onRespawn(PlayerRespawnEvent event) {
|
||||||
Player respawningPlayer = event.getPlayer();
|
Player respawningPlayer = event.getPlayer();
|
||||||
playersFromTheEnd.forEach((tuple) -> {
|
playersFromTheEnd.forEach((teleportation) -> {
|
||||||
//Check if player is actually teleporting from the end
|
//Check if player is actually teleporting from the end
|
||||||
if (tuple.getFirstValue() == respawningPlayer) {
|
if (teleportation.getPlayer() == respawningPlayer) {
|
||||||
Portal exitPortal = tuple.getSecondValue();
|
Portal exitPortal = teleportation.getExit();
|
||||||
//Need to make sure the player is allowed to exit from the portal
|
|
||||||
if (!exitPortal.isOpenFor(respawningPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Overwrite respawn location to respawn in front of the portal
|
//Overwrite respawn location to respawn in front of the portal
|
||||||
event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation()));
|
event.setRespawnLocation(exitPortal.getExit(respawningPlayer, respawningPlayer.getLocation()));
|
||||||
//Properly close the portal to prevent it from staying in a locked state until it times out
|
//Properly close the portal to prevent it from staying in a locked state until it times out
|
||||||
|
@ -5,6 +5,7 @@ import net.knarcraft.stargate.event.StargateAccessEvent;
|
|||||||
import net.knarcraft.stargate.portal.Portal;
|
import net.knarcraft.stargate.portal.Portal;
|
||||||
import net.knarcraft.stargate.portal.PortalOption;
|
import net.knarcraft.stargate.portal.PortalOption;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for deciding which actions a player is allowed to perform
|
* Helper class for deciding which actions a player is allowed to perform
|
||||||
@ -368,4 +369,47 @@ public final class PermissionHelper {
|
|||||||
return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal");
|
return portal.isOwner(player) && hasPermission(player, "stargate.destroy.personal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decide of the player can teleport through a portal
|
||||||
|
*
|
||||||
|
* @param entrancePortal <p>The portal the player is entering from</p>
|
||||||
|
* @param destination <p>The destination of the portal the player is inside</p>
|
||||||
|
* @param player <p>The player wanting to teleport</p>
|
||||||
|
* @param event <p>The move event causing the teleportation</p>
|
||||||
|
* @return <p>True if the player cannot teleport. False otherwise</p>
|
||||||
|
*/
|
||||||
|
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.isOpenFor(player)) {
|
||||||
|
Stargate.sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||||
|
entrancePortal.teleport(player, 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.sendErrorMessage(player, Stargate.getString("denyMsg"));
|
||||||
|
entrancePortal.teleport(player, entrancePortal, event);
|
||||||
|
entrancePortal.close(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Player cannot pay for teleportation
|
||||||
|
int cost = EconomyHandler.getUseCost(player, entrancePortal, destination);
|
||||||
|
if (cost > 0) {
|
||||||
|
return !EconomyHelper.payTeleportFee(entrancePortal, player, cost);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user