From 285205fe3f6cfefcc4030e920ec98b74a9aa9f91 Mon Sep 17 00:00:00 2001 From: BONNe Date: Fri, 10 Nov 2023 17:23:38 +0200 Subject: [PATCH] Fixes a bug with EntityTeleportListener (#2222) There was incorrect teleportation type detection, as target world were set to NORMAL. This prevented to detect that portal in opposite side exists, and should be linked to the correct position. --- .../teleports/EntityTeleportListener.java | 61 ++++++++++++------- .../teleports/PlayerTeleportListener.java | 10 +-- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java b/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java index 490694fa1..3cf5b0904 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/teleports/EntityTeleportListener.java @@ -7,6 +7,7 @@ package world.bentobox.bentobox.listeners.teleports; +import java.util.Objects; import java.util.UUID; import org.bukkit.Bukkit; @@ -77,8 +78,29 @@ public void onEntityPortal(EntityPortalEvent event) event.setCancelled(true); return; } - // Trigger event processor. - this.portalProcess(event, event.getTo().getWorld().getEnvironment()); + + // Check which teleportation is happening. + + World.Environment source = fromWorld.getEnvironment(); + World.Environment destination = event.getTo().getWorld().getEnvironment(); + + if (World.Environment.NETHER == source && World.Environment.NORMAL == destination || + World.Environment.NORMAL == source && World.Environment.NETHER == destination) + { + // Nether to overworld or opposite + this.portalProcess(event, World.Environment.NETHER); + } + else if (World.Environment.THE_END == source && World.Environment.NORMAL == destination || + World.Environment.NORMAL == source && World.Environment.THE_END == destination) + { + // end to overworld or opposite + this.portalProcess(event, World.Environment.THE_END); + } + else + { + // unknown teleportation + this.portalProcess(event, event.getTo().getWorld().getEnvironment()); + } } @@ -224,32 +246,24 @@ private void portalProcess(EntityPortalEvent event, World.Environment environmen } this.inTeleport.add(event.getEntity().getUniqueId()); - // Get target world. - World toWorld; - - if (environment.equals(World.Environment.NORMAL)) - { - toWorld = overWorld; - } - else - { - toWorld = this.getNetherEndWorld(overWorld, environment); - } - - if (!overWorld.equals(toWorld) && !this.isIslandWorld(overWorld, environment)) + if (fromWorld.equals(overWorld) && !this.isIslandWorld(overWorld, environment)) { // This is not island world. Use standard nether or end world teleportation. - this.handleToStandardNetherOrEnd(event, overWorld, toWorld); + this.handleToStandardNetherOrEnd(event, overWorld, environment); return; } - - if (!overWorld.equals(fromWorld) && !this.isIslandWorld(overWorld, environment)) + + if (!fromWorld.equals(overWorld) && !this.isIslandWorld(overWorld, environment)) { // If entering a portal in the other world, teleport to a portal in overworld if // there is one - this.handleFromStandardNetherOrEnd(event, overWorld, toWorld.getEnvironment()); + this.handleFromStandardNetherOrEnd(event, overWorld, environment); return; } + + // To the nether/end or overworld. + World toWorld = !fromWorld.getEnvironment().equals(environment) ? + this.getNetherEndWorld(overWorld, environment) : overWorld; // Set the destination location // If portals cannot be created, then destination is the spawn point, otherwise it's the vector @@ -286,7 +300,7 @@ private void portalProcess(EntityPortalEvent event, World.Environment environmen // Let the server teleport return; } - + if (environment.equals(World.Environment.THE_END)) { // Prevent death from hitting the ground while calculating location. @@ -324,10 +338,11 @@ private void portalProcess(EntityPortalEvent event, World.Environment environmen * Handle teleport to standard nether or end * @param event - EntityPortalEvent * @param overWorld - over world - * @param toWorld - to world + * @param environment - to target environment */ - private void handleToStandardNetherOrEnd(EntityPortalEvent event, World overWorld, World toWorld) + private void handleToStandardNetherOrEnd(EntityPortalEvent event, World overWorld, World.Environment environment) { + World toWorld = Objects.requireNonNull(this.getNetherEndWorld(overWorld, environment)); Location spawnPoint = toWorld.getSpawnLocation(); // If going to the nether and nether portals are active then just teleport to approx location @@ -345,7 +360,7 @@ private void handleToStandardNetherOrEnd(EntityPortalEvent event, World overWorl toWorld.setSpawnLocation(100, 50, 0); } - if (this.isAllowedOnServer(toWorld.getEnvironment())) + if (this.isAllowedOnServer(environment)) { // To Standard Nether or end event.setTo(spawnPoint); diff --git a/src/main/java/world/bentobox/bentobox/listeners/teleports/PlayerTeleportListener.java b/src/main/java/world/bentobox/bentobox/listeners/teleports/PlayerTeleportListener.java index 1f4b2cbfc..b461e942e 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/teleports/PlayerTeleportListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/teleports/PlayerTeleportListener.java @@ -301,7 +301,7 @@ private void portalProcess(PlayerPortalEvent event, World.Environment environmen // Find the distance from edge of island's protection and set the search radius this.getIsland(event.getTo()).ifPresent(island -> - event.setSearchRadius(this.calculateSearchRadius(event.getTo(), island))); + event.setSearchRadius(this.calculateSearchRadius(event.getTo(), island))); // Check if there is an island there or not if (this.isPastingMissingIslands(overWorld) && @@ -327,7 +327,7 @@ private void portalProcess(PlayerPortalEvent event, World.Environment environmen return; } - if (environment.equals(World.Environment.THE_END)) + if (World.Environment.THE_END.equals(environment)) { // Prevent death from hitting the ground while calculating location. event.getPlayer().setVelocity(new Vector(0,0,0)); @@ -374,14 +374,14 @@ private void handleToStandardNetherOrEnd(PlayerPortalEvent event, Location spawnPoint = toWorld.getSpawnLocation(); // If going to the nether and nether portals are active then just teleport to approx location - if (environment.equals(World.Environment.NETHER) && + if (World.Environment.NETHER.equals(environment) && this.plugin.getIWM().getWorldSettings(overWorld).isMakeNetherPortals()) { spawnPoint = event.getFrom().toVector().toLocation(toWorld); } // If spawn is set as 0,63,0 in the End then move it to 100, 50 ,0. - if (environment.equals(World.Environment.THE_END) && spawnPoint.getBlockX() == 0 && spawnPoint.getBlockZ() == 0) + if (World.Environment.THE_END.equals(environment) && spawnPoint.getBlockX() == 0 && spawnPoint.getBlockZ() == 0) { // Set to the default end spawn spawnPoint = new Location(toWorld, 100, 50, 0); @@ -413,7 +413,7 @@ private void handleToStandardNetherOrEnd(PlayerPortalEvent event, */ private void handleFromStandardNetherOrEnd(PlayerPortalEvent event, World overWorld, World.Environment environment) { - if (environment.equals(World.Environment.NETHER) && + if (World.Environment.NETHER.equals(environment) && this.plugin.getIWM().getWorldSettings(overWorld).isMakeNetherPortals()) { // Set to location directly to the from location.