mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-05 18:40:06 +01:00
Prevents repeated portaling when nether is disabled. (#1826)
* Prevents repeated portaling when nether is disabled. https://github.com/BentoBoxWorld/BentoBox/issues/1782 * Fix test
This commit is contained in:
parent
233c058bfe
commit
32638e7a87
@ -20,8 +20,8 @@ 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;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
@ -44,17 +44,12 @@ public class PortalTeleportationListener implements Listener {
|
||||
|
||||
private final BentoBox plugin;
|
||||
private Set<UUID> inPortal;
|
||||
private Set<UUID> inTeleport;
|
||||
|
||||
public PortalTeleportationListener(@NonNull BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
inPortal = new HashSet<>();
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent e) {
|
||||
// Remove player from inPortal after a teleport
|
||||
inPortal.remove(e.getPlayer().getUniqueId());
|
||||
inTeleport = new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,19 +67,13 @@ public class PortalTeleportationListener implements Listener {
|
||||
if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getLocation().getWorld()))) {
|
||||
return;
|
||||
}
|
||||
inPortal.add(uuid);
|
||||
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 (entity.getLocation().getBlock().getType().equals(Material.NETHER_PORTAL)) {
|
||||
PlayerPortalEvent en = new PlayerPortalEvent((Player)entity, e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0);
|
||||
if (!this.onIslandPortal(en)) {
|
||||
// Failed
|
||||
inPortal.remove(uuid);
|
||||
}
|
||||
} else {
|
||||
inPortal.remove(uuid);
|
||||
if (inPortal.contains(uuid)) {
|
||||
this.onIslandPortal(new PlayerPortalEvent((Player)entity, e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0));
|
||||
}
|
||||
}, 40);
|
||||
return;
|
||||
@ -129,6 +118,21 @@ public class PortalTeleportationListener implements Listener {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inPortal flag only when player exits the portal
|
||||
* @param e player move event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onExitPortal(PlayerMoveEvent e) {
|
||||
if (!inPortal.contains(e.getPlayer().getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
if (e.getTo() != null && !e.getTo().getBlock().getType().equals(Material.NETHER_PORTAL)) {
|
||||
inPortal.remove(e.getPlayer().getUniqueId());
|
||||
inTeleport.remove(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles nether or end portals
|
||||
* @param e - event
|
||||
@ -136,9 +140,9 @@ public class PortalTeleportationListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public boolean onIslandPortal(PlayerPortalEvent e) {
|
||||
return switch (e.getCause()) {
|
||||
case END_GATEWAY, END_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
|
||||
case NETHER_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
|
||||
default -> false;
|
||||
case END_GATEWAY, END_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
|
||||
case NETHER_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
|
||||
default -> false;
|
||||
};
|
||||
|
||||
}
|
||||
@ -150,18 +154,27 @@ public class PortalTeleportationListener implements Listener {
|
||||
* @return true if portal happens, false if not
|
||||
*/
|
||||
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)) {
|
||||
// Do nothing special
|
||||
return false;
|
||||
}
|
||||
// 1.14.4 requires explicit cancellation to prevent teleporting to the normal nether
|
||||
|
||||
if (!isGenerate(overWorld, env)) {
|
||||
e.setCancelled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Bukkit.getServer().getAllowNether()) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
if (inTeleport.contains(e.getEntity().getUniqueId())) {
|
||||
return false;
|
||||
}
|
||||
inTeleport.add(e.getEntity().getUniqueId());
|
||||
|
||||
// STANDARD NETHER OR END
|
||||
if (!isIslands(overWorld, env)) {
|
||||
handleStandardNetherOrEnd(e, fromWorld, overWorld, env);
|
||||
@ -194,7 +207,6 @@ public class PortalTeleportationListener implements Listener {
|
||||
&& e.getIsland().filter(i -> !hasPartnerIsland(i, env)).map(i -> {
|
||||
// No nether island present so paste the default one
|
||||
e.setCancelled(true);
|
||||
inPortal.remove(e.getEntity().getUniqueId());
|
||||
pasteNewIsland((Player)e.getEntity(), e.getTo(), i, env);
|
||||
return true;
|
||||
}).orElse(false)) {
|
||||
@ -203,7 +215,6 @@ public class PortalTeleportationListener implements Listener {
|
||||
}
|
||||
if (e.getCanCreatePortal()) {
|
||||
// Let the server teleport
|
||||
inPortal.remove(e.getEntity().getUniqueId());
|
||||
return true;
|
||||
}
|
||||
if (env.equals(Environment.THE_END)) {
|
||||
@ -228,7 +239,6 @@ public class PortalTeleportationListener implements Listener {
|
||||
.location(e.getTo())
|
||||
.portal()
|
||||
.thenRun(() -> {
|
||||
inPortal.remove(e.getEntity().getUniqueId());
|
||||
e.getEntity().setVelocity(new Vector(0,0,0));
|
||||
e.getEntity().setFallDistance(0);
|
||||
})
|
||||
@ -357,7 +367,6 @@ public class PortalTeleportationListener implements Listener {
|
||||
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
|
||||
@ -370,7 +379,6 @@ public class PortalTeleportationListener implements Listener {
|
||||
.entity(e.getEntity())
|
||||
.location(to)
|
||||
.portal()
|
||||
.thenRun(() -> inPortal.remove(e.getEntity().getUniqueId()))
|
||||
.build();
|
||||
|
||||
}
|
||||
@ -408,7 +416,7 @@ public class PortalTeleportationListener implements Listener {
|
||||
// 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()));
|
||||
plugin.getIslands().homeTeleportAsync(overWorld, (Player)e.getEntity());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ 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;
|
||||
|
||||
@ -19,6 +18,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Block;
|
||||
@ -154,6 +154,9 @@ public class PortalTeleportationListenerTest {
|
||||
BukkitScheduler sch = mock(BukkitScheduler.class);
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
when(Bukkit.getScheduler()).thenReturn(sch);
|
||||
Server server = mock(Server.class);
|
||||
when(server.getAllowNether()).thenReturn(true);
|
||||
when(Bukkit.getServer()).thenReturn(server);
|
||||
|
||||
// Locales
|
||||
LocalesManager lm = mock(LocalesManager.class);
|
||||
@ -284,7 +287,7 @@ public class PortalTeleportationListenerTest {
|
||||
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
||||
np.onIslandPortal(e);
|
||||
assertTrue(e.isCancelled());
|
||||
verify(im, times(2)).homeTeleportAsync(any(), eq(player));
|
||||
verify(im).homeTeleportAsync(any(), eq(player));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user