mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-09-30 23:57:30 +02: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.Listener;
|
||||||
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
import org.bukkit.event.entity.EntityPortalEnterEvent;
|
||||||
import org.bukkit.event.entity.EntityPortalEvent;
|
import org.bukkit.event.entity.EntityPortalEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerPortalEvent;
|
import org.bukkit.event.player.PlayerPortalEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
@ -44,17 +44,12 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
|
|
||||||
private final BentoBox plugin;
|
private final BentoBox plugin;
|
||||||
private Set<UUID> inPortal;
|
private Set<UUID> inPortal;
|
||||||
|
private Set<UUID> inTeleport;
|
||||||
|
|
||||||
public PortalTeleportationListener(@NonNull BentoBox plugin) {
|
public PortalTeleportationListener(@NonNull BentoBox plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
inPortal = new HashSet<>();
|
inPortal = new HashSet<>();
|
||||||
}
|
inTeleport = 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,19 +67,13 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getLocation().getWorld()))) {
|
if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getLocation().getWorld()))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
inPortal.add(uuid);
|
||||||
if (!Bukkit.getAllowNether() && type.equals(Material.NETHER_PORTAL)) {
|
if (!Bukkit.getAllowNether() && type.equals(Material.NETHER_PORTAL)) {
|
||||||
inPortal.add(uuid);
|
|
||||||
// Schedule a time
|
// Schedule a time
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||||
// Check again if still in portal
|
// Check again if still in portal
|
||||||
if (entity.getLocation().getBlock().getType().equals(Material.NETHER_PORTAL)) {
|
if (inPortal.contains(uuid)) {
|
||||||
PlayerPortalEvent en = new PlayerPortalEvent((Player)entity, e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0);
|
this.onIslandPortal(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);
|
|
||||||
}
|
}
|
||||||
}, 40);
|
}, 40);
|
||||||
return;
|
return;
|
||||||
@ -129,6 +118,21 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
return false;
|
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
|
* Handles nether or end portals
|
||||||
* @param e - event
|
* @param e - event
|
||||||
@ -136,9 +140,9 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public boolean onIslandPortal(PlayerPortalEvent e) {
|
public boolean onIslandPortal(PlayerPortalEvent e) {
|
||||||
return switch (e.getCause()) {
|
return switch (e.getCause()) {
|
||||||
case END_GATEWAY, END_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
|
case END_GATEWAY, END_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END);
|
||||||
case NETHER_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
|
case NETHER_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER);
|
||||||
default -> false;
|
default -> false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -150,18 +154,27 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
* @return true if portal happens, false if not
|
* @return true if portal happens, false if not
|
||||||
*/
|
*/
|
||||||
private boolean processPortal(final PlayerEntityPortalEvent e, final Environment env) {
|
private boolean processPortal(final PlayerEntityPortalEvent e, final Environment env) {
|
||||||
|
|
||||||
World fromWorld = e.getFrom().getWorld();
|
World fromWorld = e.getFrom().getWorld();
|
||||||
World overWorld = Util.getWorld(fromWorld);
|
World overWorld = Util.getWorld(fromWorld);
|
||||||
if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) {
|
if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) {
|
||||||
// Do nothing special
|
// Do nothing special
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 1.14.4 requires explicit cancellation to prevent teleporting to the normal nether
|
|
||||||
if (!isGenerate(overWorld, env)) {
|
if (!isGenerate(overWorld, env)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
return false;
|
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
|
// STANDARD NETHER OR END
|
||||||
if (!isIslands(overWorld, env)) {
|
if (!isIslands(overWorld, env)) {
|
||||||
handleStandardNetherOrEnd(e, fromWorld, 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 -> {
|
&& e.getIsland().filter(i -> !hasPartnerIsland(i, env)).map(i -> {
|
||||||
// No nether island present so paste the default one
|
// No nether island present so paste the default one
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
inPortal.remove(e.getEntity().getUniqueId());
|
|
||||||
pasteNewIsland((Player)e.getEntity(), e.getTo(), i, env);
|
pasteNewIsland((Player)e.getEntity(), e.getTo(), i, env);
|
||||||
return true;
|
return true;
|
||||||
}).orElse(false)) {
|
}).orElse(false)) {
|
||||||
@ -203,7 +215,6 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
}
|
}
|
||||||
if (e.getCanCreatePortal()) {
|
if (e.getCanCreatePortal()) {
|
||||||
// Let the server teleport
|
// Let the server teleport
|
||||||
inPortal.remove(e.getEntity().getUniqueId());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (env.equals(Environment.THE_END)) {
|
if (env.equals(Environment.THE_END)) {
|
||||||
@ -228,7 +239,6 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
.location(e.getTo())
|
.location(e.getTo())
|
||||||
.portal()
|
.portal()
|
||||||
.thenRun(() -> {
|
.thenRun(() -> {
|
||||||
inPortal.remove(e.getEntity().getUniqueId());
|
|
||||||
e.getEntity().setVelocity(new Vector(0,0,0));
|
e.getEntity().setVelocity(new Vector(0,0,0));
|
||||||
e.getEntity().setFallDistance(0);
|
e.getEntity().setFallDistance(0);
|
||||||
})
|
})
|
||||||
@ -357,7 +367,6 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
e.setTo(e.getFrom().toVector().toLocation(overWorld));
|
e.setTo(e.getFrom().toVector().toLocation(overWorld));
|
||||||
// Find distance from edge of island's protection
|
// Find distance from edge of island's protection
|
||||||
plugin.getIslands().getIslandAt(e.getFrom()).ifPresent(i -> setSeachRadius(e, i));
|
plugin.getIslands().getIslandAt(e.getFrom()).ifPresent(i -> setSeachRadius(e, i));
|
||||||
inPortal.remove(e.getEntity().getUniqueId());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Custom portals
|
// Custom portals
|
||||||
@ -370,7 +379,6 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
.entity(e.getEntity())
|
.entity(e.getEntity())
|
||||||
.location(to)
|
.location(to)
|
||||||
.portal()
|
.portal()
|
||||||
.thenRun(() -> inPortal.remove(e.getEntity().getUniqueId()))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -408,7 +416,7 @@ public class PortalTeleportationListener implements Listener {
|
|||||||
// From standard nether or end
|
// From standard nether or end
|
||||||
else if (e.getEntity() instanceof Player){
|
else if (e.getEntity() instanceof Player){
|
||||||
e.setCancelled(true);
|
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.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -19,6 +18,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -154,6 +154,9 @@ public class PortalTeleportationListenerTest {
|
|||||||
BukkitScheduler sch = mock(BukkitScheduler.class);
|
BukkitScheduler sch = mock(BukkitScheduler.class);
|
||||||
PowerMockito.mockStatic(Bukkit.class);
|
PowerMockito.mockStatic(Bukkit.class);
|
||||||
when(Bukkit.getScheduler()).thenReturn(sch);
|
when(Bukkit.getScheduler()).thenReturn(sch);
|
||||||
|
Server server = mock(Server.class);
|
||||||
|
when(server.getAllowNether()).thenReturn(true);
|
||||||
|
when(Bukkit.getServer()).thenReturn(server);
|
||||||
|
|
||||||
// Locales
|
// Locales
|
||||||
LocalesManager lm = mock(LocalesManager.class);
|
LocalesManager lm = mock(LocalesManager.class);
|
||||||
@ -284,7 +287,7 @@ public class PortalTeleportationListenerTest {
|
|||||||
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
||||||
np.onIslandPortal(e);
|
np.onIslandPortal(e);
|
||||||
assertTrue(e.isCancelled());
|
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