Nether portals (#1597)

* Add WorldSettings methods for portals

* Vanilla portals option added.

Currently defaulted on for testing. Ultimately, the game mode config can
decide if the vanilla portal is used or not.
Note that the end platform is just a set of obsidian blocks.

* Reduces search radius when close to island edge

* Adds and fixes tests

* Use EntityPortalEnterEvent instead of PlayerMoveEvent

* Removed duplication between nether and end portalling

* Code clean up

* Single event handler for nether and end.

* Created new PlayerEntityPortalEvent class to enable entity teleports

Unfortunately, PlayerPortalEvent and EntityPortalEvent are not fraternal
classes so there's no way to apply code to both except via this
abstraction class.

Tests fail.

* Places end portal always in the same place.

* Teleport entites to nether or end

Identify the teleport cause manually because there is no method.
Teleports to the End happen but seem to be slightly different locations.
Some entities will disappear, others will stick around. I don't know
why.

* Put defaults back to false.

* Create end spawn point to default point when not making end islands

* Fixed PortalTeleportationListener tests.

* Updated since tag
This commit is contained in:
tastybento 2021-02-02 17:19:22 -08:00 committed by GitHub
parent 455e662d22
commit 4e7b78832a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 622 additions and 314 deletions

View File

@ -316,7 +316,7 @@ public interface WorldSettings extends ConfigObject {
*/
@NonNull
List<String> getOnLeaveCommands();
/**
* Returns a list of commands that should be executed when the player respawns after death if {@link Flags#ISLAND_RESPAWN} is true.<br/>
* @return a list of commands.
@ -537,4 +537,22 @@ public interface WorldSettings extends ConfigObject {
{
return "create";
}
/**
* Make a nether portal when teleporting to the nether through an overworld portal
* @return true if a portal should be made
* @since 1.16.0
*/
default boolean isMakeNetherPortals() {
return false;
}
/**
* Make an end portal when teleporting to the end through an end portal
* @return true if a portal should be made
* @since 1.16.0
*/
default boolean isMakeEndPortals() {
return false;
}
}

View File

@ -0,0 +1,160 @@
package world.bentobox.bentobox.listeners;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;
/**
* Abstracts PlayerPortalEvent and EntityPortalEvent
* @author tastybento
*
*/
public class PlayerEntityPortalEvent {
private final EntityPortalEvent epe;
private final PlayerPortalEvent ppe;
/**
* Create a hybrid PlayerEntityPortalEvent
* @param epe - EntityPortalEvent
*/
public PlayerEntityPortalEvent(EntityPortalEvent epe) {
this.ppe = null;
this.epe = epe;
}
/**
* Create a hybrid PlayerEntityPortalEvent
* @param ppe - PlayerPortalEvent
*/
public PlayerEntityPortalEvent(PlayerPortalEvent ppe) {
this.ppe = ppe;
this.epe = null;
}
/**
* Returns whether the server will attempt to create a destination portal or not.
* Only applicable to {@link PlayerPortalEvent}
* @return whether there should create be a destination portal created
*/
public boolean getCanCreatePortal() {
return epe == null ? ppe.getCanCreatePortal() : false;
}
/**
* Returns the entity involved in this event
* @return Entity who is involved in this event
*/
@NonNull
public Entity getEntity() {
return epe == null ? ppe.getPlayer() : epe.getEntity();
}
/**
* Gets the location this player moved from
* @return Location the player or entity moved from
*/
@NonNull
public Location getFrom() {
return epe == null ? ppe.getFrom() : epe.getFrom();
}
/**
* Gets the location this player moved to
* @return Location the player moved to
*/
@Nullable
public Location getTo() {
return epe == null ? ppe.getTo() : epe.getTo();
}
/**
* @return true if constructed with an {@link EntityPortalEvent}
*/
public boolean isEntityPortalEvent() {
return epe != null;
}
/**
* @return true if constructed with an {@link PlayerPortalEvent}
*/
public boolean isPlayerPortalEvent() {
return ppe != null;
}
/**
* Sets the cancellation state of this event. A cancelled event will not be executed in the server, but will still pass to other plugins
* If a move or teleport event is cancelled, the player will be moved or teleported back to the Location as defined by getFrom(). This will not fire an event
* Specified by: setCancelled(...) in Cancellable
* @param cancel true if you wish to cancel this event
*/
public void setCancelled(boolean cancel) {
if (epe == null) {
ppe.setCancelled(cancel);
} else {
epe.setCancelled(cancel);
}
}
/**
* Sets whether the server should attempt to create a destination portal or not.
* Only applicable to {@link PlayerPortalEvent}
* @param canCreatePortal Sets whether there should be a destination portal created
*/
public void setCanCreatePortal(boolean canCreatePortal) {
if (ppe != null) {
ppe.setCanCreatePortal(canCreatePortal);
}
}
/**
* Set the Block radius to search in for available portals.
* @param searchRadius the radius in which to search for a portal from the location
*/
public void setSearchRadius(int searchRadius) {
if (epe == null) {
ppe.setSearchRadius(searchRadius);
} else {
epe.setSearchRadius(searchRadius);
}
}
/**
* Sets the location that this player will move to
* @param to New Location this player or entity will move to
*/
public void setTo(Location to) {
if (epe == null) {
ppe.setTo(to);
} else {
epe.setTo(to);
}
}
/**
* Get island at the from location
* @return optional island at from location
*/
public Optional<Island> getIsland() {
return BentoBox.getInstance().getIslands().getProtectedIslandAt(getFrom());
}
/**
* Get the from world
* @return from world
*/
@Nullable
public World getWorld() {
return getFrom().getWorld();
}
}

View File

@ -1,5 +1,6 @@
package world.bentobox.bentobox.listeners;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
@ -10,12 +11,14 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
@ -23,6 +26,7 @@ import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.BlueprintPaster;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
@ -57,19 +61,23 @@ public class PortalTeleportationListener implements Listener {
* @param e
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerPortal(PlayerMoveEvent e) {
UUID uuid = e.getPlayer().getUniqueId();
if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getFrom().getWorld()))) {
public void onPlayerPortal(EntityPortalEnterEvent e) {
if (!(e.getEntity() instanceof Player)) {
return;
}
if (!Bukkit.getAllowNether() && e.getPlayer().getLocation().getBlock().getType().equals(Material.NETHER_PORTAL)) {
Material type = e.getLocation().getBlock().getType();
UUID uuid = e.getEntity().getUniqueId();
if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getLocation().getWorld()))) {
return;
}
if (!Bukkit.getAllowNether() && type.equals(Material.NETHER_PORTAL)) {
inPortal.add(uuid);
// Schedule a time
Bukkit.getScheduler().runTaskLater(plugin, () -> {
// Check again if still in portal
if (e.getPlayer().getLocation().getBlock().getType().equals(Material.NETHER_PORTAL)) {
PlayerPortalEvent en = new PlayerPortalEvent(e.getPlayer(), e.getPlayer().getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0);
if (!this.onNetherPortal(en)) {
if (type.equals(Material.NETHER_PORTAL)) {
PlayerPortalEvent en = new PlayerPortalEvent((Player)e.getEntity(), e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0);
if (!this.onIslandPortal(en)) {
// Failed
inPortal.remove(uuid);
}
@ -79,9 +87,16 @@ public class PortalTeleportationListener implements Listener {
}, 40);
return;
}
if (!Bukkit.getAllowEnd() && e.getPlayer().getLocation().getBlock().getType().equals(Material.END_PORTAL)) {
PlayerPortalEvent en = new PlayerPortalEvent(e.getPlayer(), e.getPlayer().getLocation(), null, TeleportCause.END_PORTAL, 0, false, 0);
this.onEndIslandPortal(en);
// End portals are instant transfer
if (!Bukkit.getAllowEnd() && (type.equals(Material.END_PORTAL) || type.equals(Material.END_GATEWAY))) {
PlayerPortalEvent en = new PlayerPortalEvent((Player)e.getEntity(),
e.getLocation(),
null,
type.equals(Material.END_PORTAL) ? TeleportCause.END_PORTAL : TeleportCause.END_GATEWAY,
0,
false,
0);
this.onIslandPortal(en);
}
}
@ -92,124 +107,52 @@ public class PortalTeleportationListener implements Listener {
* @param e - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityPortal(EntityPortalEvent e) {
public boolean onEntityPortal(EntityPortalEvent e) {
if (plugin.getIWM().inWorld(e.getFrom())) {
// Disable entity portal transfer due to dupe glitching
e.setCancelled(true);
Optional<Material> mat = Arrays.stream(BlockFace.values())
.map(bf -> e.getFrom().getBlock().getRelative(bf).getType())
.filter(m -> m.equals(Material.NETHER_PORTAL)
|| m.equals(Material.END_PORTAL)
|| m.equals(Material.END_GATEWAY))
.findFirst();
if (!mat.isPresent()) {
e.setCancelled(true);
return false;
} else if (mat.get().equals(Material.NETHER_PORTAL)){
return processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
} else {
return processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
}
}
return false;
}
/**
* Handles end portals
* Handles nether or end portals
* @param e - event
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public boolean onEndIslandPortal(PlayerPortalEvent e) {
if (e.getCause() != TeleportCause.END_PORTAL) {
return false;
}
World fromWorld = e.getFrom().getWorld();
World overWorld = Util.getWorld(fromWorld);
if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) {
// Do nothing special
public boolean onIslandPortal(PlayerPortalEvent e) {
switch (e.getCause()) {
case END_GATEWAY:
case END_PORTAL:
return processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
case NETHER_PORTAL:
return processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
default:
return false;
}
// 1.14.4 requires explicit cancellation to prevent teleporting to the normal nether
if (!plugin.getIWM().isEndGenerate(overWorld)) {
e.setCancelled(true);
return false;
}
// STANDARD END
if (!plugin.getIWM().isEndIslands(overWorld)) {
if (fromWorld.getEnvironment() != Environment.THE_END) {
if (Bukkit.getAllowEnd()) {
// To Standard end
e.setTo(plugin.getIWM().getEndWorld(overWorld).getSpawnLocation());
} else {
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(plugin.getIWM().getEndWorld(overWorld).getSpawnLocation())
.thenRun(() -> inPortal.remove(e.getPlayer().getUniqueId()))
.build();
}
}
// From standard end - check if player has an island to go to
else if (plugin.getIslands().hasIsland(overWorld, e.getPlayer().getUniqueId())
|| plugin.getIslands().inTeam(overWorld, e.getPlayer().getUniqueId())) {
e.setCancelled(true);
plugin.getIslands().homeTeleportAsync(overWorld, e.getPlayer());
}
// No island, so just do nothing
return false;
}
// FROM END
// If entering an ender portal in the End.
if (fromWorld.getEnvironment() == Environment.THE_END) {
// If this is from the island nether, then go to the same vector, otherwise try island home location
Location to = plugin.getIslands().getIslandAt(e.getFrom()).map(i -> i.getSpawnPoint(Environment.NORMAL)).orElseGet(() -> e.getFrom().toVector().toLocation(overWorld));
e.setCancelled(true);
// Else other worlds teleport to the overworld
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(to)
.portal()
.build();
return true;
}
// TO END
World endWorld = plugin.getIWM().getEndWorld(overWorld);
// If this is to island End, then go to the same vector, otherwise try spawn
Optional<Island> optionalIsland = plugin.getIslands().getIslandAt(e.getFrom());
Location to = optionalIsland.map(i -> i.getSpawnPoint(Environment.THE_END)).orElseGet(() -> e.getFrom().toVector().toLocation(endWorld));
e.setCancelled(true);
// Check if there is a missing end island
if (plugin.getIWM().isPasteMissingIslands(overWorld)
&& !plugin.getIWM().isUseOwnGenerator(overWorld)
&& plugin.getIWM().isEndGenerate(overWorld)
&& plugin.getIWM().isEndIslands(overWorld)
&& plugin.getIWM().getEndWorld(overWorld) != null
&& optionalIsland.filter(i -> !i.hasEndIsland())
.map(i -> {
// No end island present so paste the default one
pasteNewIsland(e.getPlayer(), to, i, Environment.THE_END);
return true;
}).orElse(false)) {
// We are done here
return true;
}
// Set player's velocity and fall distance to 0
e.getPlayer().setVelocity(new Vector(0,0,0));
e.getPlayer().setFallDistance(0);
// Else other worlds teleport to the end
// Set player's velocity to zero one tick after cancellation
// Teleport
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(to)
.thenRun(() -> {
e.getPlayer().setVelocity(new Vector(0,0,0));
e.getPlayer().setFallDistance(0);
})
.build();
return true;
}
/**
* Handles nether portals.
* Process the portal action
* @param e - event
* @return false if teleport does not happen, true if it does
* @param env - environment that this relates to - NETHER or THE_END
* @return true if portal happens, false if not
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) // Use HIGH to allow Multiverse first shot
public boolean onNetherPortal(PlayerPortalEvent e) {
if (e.getCause() != TeleportCause.NETHER_PORTAL) {
return false;
}
private boolean processPortal(final PlayerEntityPortalEvent e, final Environment env) {
World fromWorld = e.getFrom().getWorld();
World overWorld = Util.getWorld(fromWorld);
if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) {
@ -217,77 +160,262 @@ public class PortalTeleportationListener implements Listener {
return false;
}
// 1.14.4 requires explicit cancellation to prevent teleporting to the normal nether
if (!plugin.getIWM().isNetherGenerate(overWorld)) {
if (!isGenerate(overWorld, env)) {
e.setCancelled(true);
return false;
}
// STANDARD NETHER
if (!plugin.getIWM().isNetherIslands(overWorld)) {
if (fromWorld.getEnvironment() != Environment.NETHER) {
if (Bukkit.getAllowNether()) {
// To Standard Nether
e.setTo(plugin.getIWM().getNetherWorld(overWorld).getSpawnLocation());
} else {
// Teleport to standard nether
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(plugin.getIWM().getNetherWorld(fromWorld).getSpawnLocation())
.portal()
.build();
}
}
// From standard nether
else {
e.setCancelled(true);
plugin.getIslands().homeTeleportAsync(overWorld, e.getPlayer()).thenAccept(b -> inPortal.remove(e.getPlayer().getUniqueId()));
}
// STANDARD NETHER OR END
if (!isIslands(overWorld, env)) {
handleStandardNetherOrEnd(e, fromWorld, overWorld, env);
return true;
}
// FROM NETHER
// If entering a nether portal in the nether, teleport to portal in overworld if there is one
if (fromWorld.getEnvironment() == Environment.NETHER) {
// If this is from the island nether, then go to the same vector, otherwise try island home location
Location to = plugin.getIslands().getIslandAt(e.getFrom()).map(i -> i.getSpawnPoint(Environment.NORMAL)).orElseGet(() -> e.getFrom().toVector().toLocation(overWorld));
e.setCancelled(true);
// Else other worlds teleport to the nether
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(to)
.portal()
.thenRun(() -> inPortal.remove(e.getPlayer().getUniqueId()))
.build();
// FROM NETHER OR END
// If entering a portal in the other world, teleport to a portal in overworld if there is one
if (fromWorld.getEnvironment().equals(env)) {
handleFromNetherOrEnd(e, overWorld, env);
return true;
}
// TO NETHER
World nether = plugin.getIWM().getNetherWorld(overWorld);
// If this is to island nether, then go to the same vector, otherwise try spawn
Optional<Island> optionalIsland = plugin.getIslands().getIslandAt(e.getFrom());
Location to = optionalIsland.map(i -> i.getSpawnPoint(Environment.NETHER)).orElseGet(() -> e.getFrom().toVector().toLocation(nether));
e.setCancelled(true);
// TO NETHER OR END
World toWorld = getNetherEndWorld(overWorld, env);
// Set whether portals should be created or not
e.setCanCreatePortal(plugin.getIWM().getAddon(overWorld).map(gm -> isMakePortals(gm, env)).orElse(false));
// Set the destination location
// If portals cannot be created, then destination is the spawn point, otherwise it's the vector
e.setTo(getTo(e, env, toWorld));
// Find the distance from edge of island's protection and set the search radius
e.getIsland().ifPresent(i -> setSeachRadius(e, i));
// Check if there is an island there or not
if (plugin.getIWM().isPasteMissingIslands(overWorld) &&
!plugin.getIWM().isUseOwnGenerator(overWorld)
&& plugin.getIWM().isNetherGenerate(overWorld)
&& plugin.getIWM().isNetherIslands(overWorld)
&& plugin.getIWM().getNetherWorld(overWorld) != null
&& optionalIsland.filter(i -> !i.hasNetherIsland()).map(i -> {
if (e.getEntity().getType().equals(EntityType.PLAYER)
&& plugin.getIWM().isPasteMissingIslands(overWorld)
&& !plugin.getIWM().isUseOwnGenerator(overWorld)
&& isGenerate(overWorld, env)
&& isIslands(overWorld, env)
&& getNetherEndWorld(overWorld, env) != null
&& e.getIsland().filter(i -> !hasPartnerIsland(i, env)).map(i -> {
// No nether island present so paste the default one
pasteNewIsland(e.getPlayer(), to, i, Environment.NETHER);
e.setCancelled(true);
inPortal.remove(e.getEntity().getUniqueId());
pasteNewIsland((Player)e.getEntity(), e.getTo(), i, env);
return true;
}).orElse(false)) {
// All done here
return true;
}
// Else other worlds teleport to the nether
new SafeSpotTeleport.Builder(plugin)
.entity(e.getPlayer())
.location(to)
.portal()
.thenRun(() -> inPortal.remove(e.getPlayer().getUniqueId()))
.build();
if (e.getCanCreatePortal()) {
// Let the server teleport
inPortal.remove(e.getEntity().getUniqueId());
return true;
}
if (env.equals(Environment.THE_END)) {
// Prevent death from hitting the ground
e.getEntity().setVelocity(new Vector(0,0,0));
e.getEntity().setFallDistance(0);
}
// If there is a portal to go to already, then the player will go there
Bukkit.getScheduler().runTask(plugin, () -> {
if (!e.getEntity().getWorld().equals(toWorld)) {
// Else manually teleport entity
new SafeSpotTeleport.Builder(plugin)
.entity(e.getEntity())
.location(e.getTo())
.portal()
.thenRun(() -> {
inPortal.remove(e.getEntity().getUniqueId());
e.getEntity().setVelocity(new Vector(0,0,0));
e.getEntity().setFallDistance(0);
})
.build();
}
});
return true;
}
/**
* Set the destination of this portal action
* @param e - event
* @param env - environment
* @param toWorld - to world
*/
Location getTo(PlayerEntityPortalEvent e, Environment env, World toWorld) {
// Null check - not that useful
if (e.getFrom().getWorld() == null || toWorld == null) {
return null;
}
if (!e.getCanCreatePortal()) {
// Legacy portaling
return e.getIsland().map(i -> i.getSpawnPoint(env)).orElse(e.getFrom().toVector().toLocation(toWorld));
}
// Make portals
// For anywhere other than the end - it is the player's location that is used
if (!env.equals(Environment.THE_END)) {
return e.getFrom().toVector().toLocation(toWorld);
}
// If the-end then we want the platform to always be generated in the same place no matter where
// they enter the portal
final int x = e.getFrom().getBlockX();
final int z = e.getFrom().getBlockZ();
final int y = e.getFrom().getBlockY();
int i = x;
int j = z;
int k = y;
// If the from is not a portal, then we have to find it
if (!e.getFrom().getBlock().getType().equals(Material.END_PORTAL)) {
// Find the portal - due to speed, it is possible that the player will be below or above the portal
for (k = 0; (k < e.getWorld().getMaxHeight()) && !e.getWorld().getBlockAt(x, k, z).getType().equals(Material.END_PORTAL); k++);
}
// Find the maximum x and z corner
for (; (i < x + 5) && e.getWorld().getBlockAt(i, k, z).getType().equals(Material.END_PORTAL); i++);
for (; (j < z + 5) && e.getWorld().getBlockAt(x, k, j).getType().equals(Material.END_PORTAL); j++);
return new Location(toWorld, i, k, j);
}
/**
* Check if vanilla portals should be used
* @param gm - game mode
* @param env - environment
* @return true or false
*/
private boolean isMakePortals(GameModeAddon gm, Environment env) {
return env.equals(Environment.NETHER) ? gm.getWorldSettings().isMakeNetherPortals() : gm.getWorldSettings().isMakeEndPortals();
}
/**
* Check if nether or end are generated
* @param gm - game mode
* @param env - environment
* @return true or false
*/
private boolean isGenerate(World overWorld, Environment env) {
return env.equals(Environment.NETHER) ? plugin.getIWM().isNetherGenerate(overWorld) : plugin.getIWM().isEndGenerate(overWorld);
}
/**
* Check if nether or end islands are generated
* @param gm - game mode
* @param env - environment
* @return true or false
*/
private boolean isIslands(World overWorld, Environment env) {
return env.equals(Environment.NETHER) ? plugin.getIWM().isNetherIslands(overWorld) : plugin.getIWM().isEndIslands(overWorld);
}
/**
* Get the nether or end world
* @param gm - game mode
* @param env - environment
* @return nether or end world
*/
private World getNetherEndWorld(World overWorld, Environment env) {
return env.equals(Environment.NETHER) ? plugin.getIWM().getNetherWorld(overWorld) : plugin.getIWM().getEndWorld(overWorld);
}
/**
* Check if the island has a nether or end island already
* @param gm - game mode
* @param env - environment
* @return true or false
*/
private boolean hasPartnerIsland(Island i, Environment env) {
return env.equals(Environment.NETHER) ? i.hasNetherIsland() : i.hasEndIsland();
}
/**
* Check if the default nether or end are allowed by the server settings
* @param gm - game mode
* @param env - environment
* @return true or false
*/
private boolean isAllowedOnServer(Environment env) {
return env.equals(Environment.NETHER) ? Bukkit.getAllowNether() : Bukkit.getAllowEnd();
}
/**
* Handle teleport from nether or end to overworld
* @param e - event
* @param overWorld - over world
* @param env - environment
*/
private void handleFromNetherOrEnd(PlayerEntityPortalEvent e, World overWorld, Environment env) {
// Standard portals
if (plugin.getIWM().getAddon(overWorld).map(gm -> isMakePortals(gm, env)).orElse(false)) {
e.setTo(e.getFrom().toVector().toLocation(overWorld));
// Find distance from edge of island's protection
plugin.getIslands().getIslandAt(e.getFrom()).ifPresent(i -> setSeachRadius(e, i));
inPortal.remove(e.getEntity().getUniqueId());
return;
}
// Custom portals
e.setCancelled(true);
// If this is from the island nether or end, then go to the same vector, otherwise try island home location
Location to = plugin.getIslands().getIslandAt(e.getFrom()).map(i -> i.getSpawnPoint(Environment.NORMAL)).orElse(e.getFrom().toVector().toLocation(overWorld));
e.setTo(to);
// Else other worlds teleport to the nether
new SafeSpotTeleport.Builder(plugin)
.entity(e.getEntity())
.location(to)
.portal()
.thenRun(() -> inPortal.remove(e.getEntity().getUniqueId()))
.build();
}
/**
* Handle teleport from or to standard nether or end
* @param e
* @param fromWorld
* @param overWorld
* @param env
*/
private void handleStandardNetherOrEnd(PlayerEntityPortalEvent e, World fromWorld, World overWorld, Environment env) {
if (fromWorld.getEnvironment() != env) {
World toWorld = getNetherEndWorld(overWorld, env);
Location spawnPoint = toWorld.getSpawnLocation();
// If spawn is set as 0,63,0 in the End then move it to 100, 50 ,0.
if (env.equals(Environment.THE_END) && spawnPoint.toVector().equals(new Vector(0,63,0))) {
// Set to the default end spawn
spawnPoint = new Location(toWorld, 100, 50, 0);
toWorld.setSpawnLocation(100, 50, 0);
}
if (isAllowedOnServer(env)) {
// To Standard Nether or end
plugin.logDebug("Spawn = " + spawnPoint);
e.setTo(spawnPoint);
} else {
plugin.logDebug("Spawn = " + spawnPoint);
// Teleport to standard nether or end
new SafeSpotTeleport.Builder(plugin)
.entity(e.getEntity())
.location(spawnPoint)
.portal()
.build();
}
}
// From standard nether or end
else if (e.getEntity() instanceof Player){
e.setCancelled(true);
plugin.getIslands().homeTeleportAsync(overWorld, (Player)e.getEntity()).thenAccept(b -> inPortal.remove(e.getEntity().getUniqueId()));
}
}
void setSeachRadius(PlayerEntityPortalEvent e, Island i) {
if (!i.onIsland(e.getFrom())) return;
// Find max x or max z
int x = Math.abs(i.getCenter().getBlockX() - e.getFrom().getBlockX());
int z = Math.abs(i.getCenter().getBlockZ() - e.getFrom().getBlockZ());
int diff = i.getProtectionRange() - Math.max(x, z);
if (diff > 0 && diff < 128) {
e.setSearchRadius(diff);
}
}
/**
* Pastes the default nether or end island and teleports the player to the island's spawn point
* @param player - player to teleport after pasting

View File

@ -1,11 +1,13 @@
package world.bentobox.bentobox.listeners;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -16,9 +18,12 @@ import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.player.PlayerPortalEvent;
@ -40,6 +45,7 @@ import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.BlueprintPaster;
@ -79,6 +85,10 @@ public class PortalTeleportationListenerTest {
private BlueprintsManager bpm;
@Mock
private GameModeAddon gameModeAddon;
@Mock
private WorldSettings ws;
@Mock
private Player player;
@Before
public void setUp() throws Exception {
@ -102,7 +112,7 @@ public class PortalTeleportationListenerTest {
when(iwm.getNetherSpawnRadius(any())).thenReturn(100);
when(plugin.getIWM()).thenReturn(iwm);
PowerMockito.mockStatic(Util.class);
PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS);
when(Util.getWorld(any())).thenReturn(world);
// Settings
@ -167,7 +177,11 @@ public class PortalTeleportationListenerTest {
defaultBB.setBlueprint(World.Environment.THE_END, bp);
when(bpm.getDefaultBlueprintBundle(any())).thenReturn(defaultBB);
when(bpm.getBlueprints(any())).thenReturn(Collections.singletonMap("blueprintname", bp));
// Paster
// World Settings
when(gameModeAddon.getWorldSettings()).thenReturn(ws);
// Player
when(player.getType()).thenReturn(EntityType.PLAYER);
}
@ -183,26 +197,26 @@ public class PortalTeleportationListenerTest {
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalNotEnd() {
public void testonIslandPortalNotEnd() {
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
// Wrong cause
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.CHORUS_FRUIT);
np.onEndIslandPortal(e);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.CHORUS_FRUIT);
np.onIslandPortal(e);
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalNoEndWorldGenerated() {
public void testonIslandPortalNoEndWorldGenerated() {
Location from = mock(Location.class);
// Teleport from world to end
when(from.getWorld()).thenReturn(world);
@ -210,46 +224,46 @@ public class PortalTeleportationListenerTest {
// No end world
when(iwm.isEndGenerate(any())).thenReturn(false);
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.END_PORTAL);
np.onEndIslandPortal(e);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.END_PORTAL);
np.onIslandPortal(e);
assertTrue(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalWrongWorld() {
public void testonIslandPortalWrongWorld() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location loc = mock(Location.class);
// Right cause, end exists, wrong world
when(loc.getWorld()).thenReturn(mock(World.class));
wrongWorld();
PlayerPortalEvent e = new PlayerPortalEvent(null, loc, null, TeleportCause.END_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, loc, null, TeleportCause.END_PORTAL);
when(iwm.isEndGenerate(world)).thenReturn(true);
np.onEndIslandPortal(e);
np.onIslandPortal(e);
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalNullWorld() {
public void testonIslandPortalNullWorld() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location loc = mock(Location.class);
when(loc.getWorld()).thenReturn(null);
PlayerPortalEvent e = new PlayerPortalEvent(null, loc, null, TeleportCause.END_PORTAL);
assertFalse(np.onEndIslandPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, loc, null, TeleportCause.END_PORTAL);
assertFalse(np.onIslandPortal(e));
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalHome() {
public void testonIslandPortalHome() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from end
@ -262,27 +276,29 @@ public class PortalTeleportationListenerTest {
// Right cause, end exists, right world
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.END_PORTAL);
when(iwm.isEndGenerate(world)).thenReturn(true);
np.onEndIslandPortal(e);
assertFalse(e.isCancelled());
// No island for player
when(im.hasIsland(any(), any(UUID.class))).thenReturn(false);
np.onIslandPortal(e);
assertTrue(e.isCancelled());
// Give player an island
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
np.onEndIslandPortal(e);
np.onIslandPortal(e);
assertTrue(e.isCancelled());
verify(im).homeTeleportAsync(any(), eq(player));
verify(im, times(2)).homeTeleportAsync(any(), eq(player));
}
/**
* Test method for {@link PortalTeleportationListener#onEndIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnEndIslandPortalNonBentoBoxWorld() {
public void testonIslandPortalNonBentoBoxWorld() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from nether to world
when(from.getWorld()).thenReturn(mock(World.class));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onEndIslandPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onIslandPortal(e));
// Verify
assertFalse(e.isCancelled());
verify(iwm, never()).isEndGenerate(any());
@ -295,8 +311,14 @@ public class PortalTeleportationListenerTest {
public void testOnEntityPortal() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Entity ent = mock(Entity.class);
when(ent.getType()).thenReturn(EntityType.VILLAGER);
when(ent.getWorld()).thenReturn(world);
Location from = mock(Location.class);
when(from.getWorld()).thenReturn(mock(World.class));
when(from.getWorld()).thenReturn(world);
Block block = mock(Block.class);
when(from.getBlock()).thenReturn(block);
when(block.getRelative(any())).thenReturn(block);
when(block.getType()).thenReturn(Material.NETHER_PORTAL);
// Not in world
wrongWorld();
EntityPortalEvent e = new EntityPortalEvent(ent, from, null);
@ -307,49 +329,49 @@ public class PortalTeleportationListenerTest {
when(iwm.inWorld(any(Location.class))).thenReturn(true);
e = new EntityPortalEvent(ent, from, null);
np.onEntityPortal(e);
assertTrue(e.isCancelled());
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalNotPortal() {
public void testonIslandPortalNotPortal() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
PlayerPortalEvent e = new PlayerPortalEvent(null, null, null, TeleportCause.COMMAND);
assertFalse(np.onNetherPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, null, null, TeleportCause.COMMAND);
assertFalse(np.onIslandPortal(e));
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalWrongWorld() {
public void testonIslandPortalWrongWorldNether() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
when(from.getWorld()).thenReturn(mock(World.class));
wrongWorld();
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onNetherPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onIslandPortal(e));
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherIsland() {
public void testonIslandPortalFromWorldToNetherIsland() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
assertTrue(np.onNetherPortal(e));
// Verify
assertTrue(e.isCancelled());
assertTrue(np.onIslandPortal(e));
// Event is not canceled
assertFalse(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
// Do not go to spawn
@ -357,105 +379,52 @@ public class PortalTeleportationListenerTest {
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherIslandPasteBlueprintError() {
public void testonIslandPortalFromWorldToNetherIslandWithSpawnDefined() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
Location to = mock(Location.class);
when(to.getWorld()).thenReturn(world);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
// Paste
when(iwm.isPasteMissingIslands(any())).thenReturn(true);
Island isle = mock(Island.class);
when(isle.getWorld()).thenReturn(world);
when(isle.hasEndIsland()).thenReturn(false);
Optional<Island> island = Optional.of(isle );
when(im.getIslandAt(any())).thenReturn(island);
// No bp
when(bpm.getBlueprints(any())).thenReturn(Collections.emptyMap());
// Test
assertTrue(np.onNetherPortal(e));
// Error
verify(plugin).logError(eq("Could not paste default island in nether or end. Is there a nether-island or end-island blueprint?"));
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherIslandPasteBlueprint() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
// Paste
when(iwm.isPasteMissingIslands(any())).thenReturn(true);
Island isle = mock(Island.class);
when(isle.getWorld()).thenReturn(world);
when(isle.getCenter()).thenReturn(from);
when(isle.hasEndIsland()).thenReturn(false);
Optional<Island> island = Optional.of(isle );
when(im.getIslandAt(any())).thenReturn(island);
// Test
assertTrue(np.onNetherPortal(e));
// Error
verify(plugin, never()).logError(eq("Could not paste default island in nether or end. Is there a nether-island or end-island blueprint?"));
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherIslandWithSpawnDefined() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, to, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
when(iwm.getNetherWorld(any())).thenReturn(nether);
Island island = mock(Island.class);
Location spawnLoc = mock(Location.class);
when(spawnLoc.getWorld()).thenReturn(world);
when(island.getSpawnPoint(any())).thenReturn(spawnLoc);
Optional<Island> optionalIsland = Optional.of(island);
// Island exists at location
when(im.getIslandAt(any())).thenReturn(optionalIsland);
assertTrue(np.onNetherPortal(e));
assertTrue(np.onIslandPortal(e));
// Verify
assertTrue(e.isCancelled());
// If nether islands, then to spawn location
verify(island).getSpawnPoint(eq(Environment.NETHER));
// Do not go to from
verify(from, never()).toVector();
assertFalse(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
// Do not go to spawn
verify(nether, never()).getSpawnLocation();
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherIslandWithNoSpawnDefined() {
public void testonIslandPortalFromWorldToNetherIslandWithNoSpawnDefined() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
@ -467,9 +436,9 @@ public class PortalTeleportationListenerTest {
when(im.getIslandAt(any())).thenReturn(optionalIsland);
assertTrue(np.onNetherPortal(e));
assertTrue(np.onIslandPortal(e));
// Verify
assertTrue(e.isCancelled());
assertFalse(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
// Do not go to spawn
@ -477,30 +446,30 @@ public class PortalTeleportationListenerTest {
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromWorldToNetherStandard() {
public void testonIslandPortalFromWorldToNetherStandard() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from world to nether
when(from.getWorld()).thenReturn(world);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands inactive
when(iwm.isNetherIslands(any())).thenReturn(false);
when(iwm.isNetherGenerate(any())).thenReturn(true);
assertTrue(np.onNetherPortal(e));
assertTrue(np.onIslandPortal(e));
// Verify
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* @throws Exception
*/
@Test
public void testOnNetherPortalFromNetherStandard() throws Exception {
public void testonIslandPortalFromNetherStandard() throws Exception {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from nether to world
@ -515,26 +484,26 @@ public class PortalTeleportationListenerTest {
when(iwm.isNetherGenerate(any())).thenReturn(true);
// Player should be teleported to their island
assertTrue(np.onNetherPortal(e));
assertTrue(np.onIslandPortal(e));
// Verify
assertTrue(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalFromNetherIsland() {
public void testonIslandPortalFromNetherIsland() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from nether to world
when(from.getWorld()).thenReturn(nether);
when(from.toVector()).thenReturn(new Vector(1,2,3));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
// Nether islands active
when(iwm.isNetherIslands(any())).thenReturn(true);
when(iwm.isNetherGenerate(any())).thenReturn(true);
assertTrue(np.onNetherPortal(e));
assertTrue(np.onIslandPortal(e));
// Verify
assertTrue(e.isCancelled());
// If regular nether, then to = island location
@ -543,48 +512,81 @@ public class PortalTeleportationListenerTest {
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherIslandPortalNullLocation() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location loc = null;
PlayerPortalEvent e = new PlayerPortalEvent(null, loc, null, TeleportCause.END_PORTAL);
assertFalse(np.onNetherPortal(e));
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalNullWorld() {
public void testonIslandPortalNullWorldNether() {
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from nether to world
when(from.getWorld()).thenReturn(null);
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onNetherPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onIslandPortal(e));
// Verify
assertFalse(e.isCancelled());
}
/**
* Test method for {@link PortalTeleportationListener#onNetherPortal(org.bukkit.event.player.PlayerPortalEvent)}.
* Test method for {@link PortalTeleportationListener#onIslandPortal(org.bukkit.event.player.PlayerPortalEvent)}.
*/
@Test
public void testOnNetherPortalNonBentoBoxWorld() {
public void testonIslandPortalNonBentoBoxWorldNether() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
Location from = mock(Location.class);
// Teleport from nether to world
when(from.getWorld()).thenReturn(mock(World.class));
PlayerPortalEvent e = new PlayerPortalEvent(null, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onNetherPortal(e));
PlayerPortalEvent e = new PlayerPortalEvent(player, from, null, TeleportCause.NETHER_PORTAL);
assertFalse(np.onIslandPortal(e));
// Verify
assertFalse(e.isCancelled());
verify(iwm, never()).isNetherGenerate(any());
}
/**
* Test method for {@link PortalTeleportationListener#setSeachRadius(PlayerPortalEvent, Island)
*/
@Test
public void testSetSeachRadius() {
Location from = mock(Location.class);
Location to = mock(Location.class);
PlayerPortalEvent e = new PlayerPortalEvent(p, from, to);
Island island = mock(Island.class);
when(island.onIsland(any())).thenReturn(true);
Location center = mock(Location.class);
when(center.getBlockX()).thenReturn(200);
when(center.getBlockZ()).thenReturn(200);
when(island.getCenter()).thenReturn(center);
when(island.getProtectionRange()).thenReturn(200);
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
when(from.getBlockZ()).thenReturn(205);
assertEquals(128, e.getSearchRadius());
for (int x = 200; x < 410; x++) {
when(from.getBlockX()).thenReturn(x);
np.setSeachRadius(new PlayerEntityPortalEvent(e), island);
if (x >= 400) {
assertEquals(1, e.getSearchRadius());
} else if (x < 273) {
assertEquals(128, e.getSearchRadius());
} else if (x < 400) {
assertEquals(400 - x, e.getSearchRadius());
}
}
}
/**
* Test method for {@link PortalTeleportationListener#setSeachRadius(PlayerPortalEvent, Island)
*/
@Test
public void testSetSeachRadiusNotOnIsland() {
Location from = mock(Location.class);
PlayerPortalEvent e = new PlayerPortalEvent(p, from, null);
Island island = mock(Island.class);
when(island.onIsland(any())).thenReturn(false);
PortalTeleportationListener np = new PortalTeleportationListener(plugin);
np.setSeachRadius(new PlayerEntityPortalEvent(e), island);
assertEquals(128, e.getSearchRadius());
}
}