diff --git a/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java b/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java index 1ce4abded..14ed0a249 100644 --- a/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java +++ b/src/main/java/com/iridium/iridiumskyblock/IridiumSkyblock.java @@ -189,6 +189,7 @@ public void registerListeners() { Bukkit.getPluginManager().registerEvents(new PlayerInteractListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerRespawnEventListener(), this); Bukkit.getPluginManager().registerEvents(new EntityDamageListener(), this); + Bukkit.getPluginManager().registerEvents(new EntityPortalListener(), this); if(!XReflection.supports(15)) Bukkit.getPluginManager().registerEvents(new PortalCreateListener(), this); } diff --git a/src/main/java/com/iridium/iridiumskyblock/listeners/EntityPortalListener.java b/src/main/java/com/iridium/iridiumskyblock/listeners/EntityPortalListener.java new file mode 100644 index 000000000..04f1adbc5 --- /dev/null +++ b/src/main/java/com/iridium/iridiumskyblock/listeners/EntityPortalListener.java @@ -0,0 +1,108 @@ +package com.iridium.iridiumskyblock.listeners; + +import com.iridium.iridiumskyblock.IridiumSkyblock; +import com.iridium.iridiumskyblock.database.Island; +import com.iridium.iridiumskyblock.utils.LocationUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEvent; + +import java.util.Objects; +import java.util.Optional; + +public class EntityPortalListener implements Listener { + + @EventHandler(ignoreCancelled = true) + public void onEntityPortal(EntityPortalEvent event) { + + Entity entity = event.getEntity(); + + Optional islandCheck = IridiumSkyblock.getInstance().getTeamManager().getTeamViaLocation(entity.getLocation()); + + // We want to allow teleportation from a non-skyblock world into a skyblock world, or from no island to an island. + // We don't care if the entity is not within an island. + if(!islandCheck.isPresent()) { + return; + } + + World worldFrom = event.getFrom().getWorld(); + World worldTo = event.getTo().getWorld(); + + World overworld = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.NORMAL); + World nether = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.NETHER); + World end = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.THE_END); + + // We don't care if the entity travels within the same world or dimension. + if((worldTo != null) && (worldFrom == worldTo || worldFrom.getEnvironment() == worldTo.getEnvironment())) { + return; + } + + Island island = islandCheck.get(); + int level = island.getLevel(); + Location entityLocation = entity.getLocation(); + World destination; + + // ================== + // | NETHER CHECK | + // ================== + + if (entityLocation.getBlock().getType() != Material.END_PORTAL) { + // We don't teleport if the Nether is disabled. + if(worldTo == null && nether == null) { + event.setCancelled(true); + return; + } + + // We only teleport if the island's level allows it. + if(level < IridiumSkyblock.getInstance().getConfiguration().netherUnlockLevel) { + event.setCancelled(true); + return; + } + + // Set teleport location + destination = Objects.equals(worldFrom, nether) ? overworld : nether; + } + + // =============== + // | END CHECK | + // =============== + + else { + // We don't teleport if the End is disabled. + if(worldTo == null && end == null) { + event.setCancelled(true); + return; + } + + // We only teleport if the island's level allows it. + if(level < IridiumSkyblock.getInstance().getConfiguration().endUnlockLevel) { + event.setCancelled(true); + return; + } + + // Set teleport location + destination = Objects.equals(worldFrom, end) ? overworld : end; + } + + event.setTo(island.getCenter(destination)); + + // Finalize the teleport + Location location = LocationUtils.getSafeLocation(island.getCenter(destination), island); + + if (location == null) { + event.setCancelled(true); + return; + } + + location.setY(location.getY() + 1); + // version example: 1.20.4-R0.1-SNAPSHOT (we need 20) + // will need to be updated for 26.x + if (Integer.parseInt(Bukkit.getBukkitVersion().substring(2, 4)) >= 15) event.setCanCreatePortal(false); + event.setTo(location); + } +} diff --git a/src/main/java/com/iridium/iridiumskyblock/listeners/PlayerPortalListener.java b/src/main/java/com/iridium/iridiumskyblock/listeners/PlayerPortalListener.java index e55ae3a95..0ba5c1646 100644 --- a/src/main/java/com/iridium/iridiumskyblock/listeners/PlayerPortalListener.java +++ b/src/main/java/com/iridium/iridiumskyblock/listeners/PlayerPortalListener.java @@ -3,70 +3,123 @@ import com.cryptomorin.xseries.reflection.XReflection; import com.iridium.iridiumcore.utils.StringUtils; import com.iridium.iridiumskyblock.IridiumSkyblock; +import com.iridium.iridiumskyblock.database.Island; import com.iridium.iridiumskyblock.utils.LocationUtils; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; import java.util.Objects; +import java.util.Optional; public class PlayerPortalListener implements Listener { @EventHandler(ignoreCancelled = true) public void onPlayerPortal(PlayerPortalEvent event) { - IridiumSkyblock.getInstance().getTeamManager().getTeamViaPlayerLocation(event.getPlayer(), event.getFrom()).ifPresent(island -> { - if (event.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) { - if (island.getLevel() < IridiumSkyblock.getInstance().getConfiguration().netherUnlockLevel) { - event.getPlayer().sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().netherLocked - .replace("%level%", String.valueOf(IridiumSkyblock.getInstance().getConfiguration().netherUnlockLevel)) - .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) - )); - event.setCancelled(true); - return; - } - World nether = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.NETHER); - if (nether == null) { - event.getPlayer().sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().netherIslandsDisabled - .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) - )); - event.setCancelled(true); - return; - } - World world = Objects.equals(event.getFrom().getWorld(), nether) ? IridiumSkyblock.getInstance().getTeamManager().getWorld(World.Environment.NORMAL) : nether; - event.setTo(island.getCenter(world)); - } else if (event.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL) { - if (island.getLevel() < IridiumSkyblock.getInstance().getConfiguration().endUnlockLevel) { - event.getPlayer().sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().endLocked - .replace("%level%", String.valueOf(IridiumSkyblock.getInstance().getConfiguration().endUnlockLevel)) - .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) - )); - event.setCancelled(true); - return; - } - World end = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.THE_END); - if (end == null) { - event.getPlayer().sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().endIslandsDisabled - .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) - )); - event.setCancelled(true); - return; - } - World world = Objects.equals(event.getFrom().getWorld(), end) ? IridiumSkyblock.getInstance().getTeamManager().getWorld(World.Environment.NORMAL) : end; - Location location = LocationUtils.getSafeLocation(island.getCenter(world), island); - if (location == null) { - event.getPlayer().sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().noSafeLocation - .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) - )); - event.setCancelled(true); - return; - } - location.setY(location.getY() + 1); - if (XReflection.supports(15)) event.setCanCreatePortal(false); - event.setTo(location); + + Player player = event.getPlayer(); + + Optional islandCheck = IridiumSkyblock.getInstance().getTeamManager().getTeamViaPlayerLocation(player); + + // We want to allow teleportation from a non-skyblock world into a skyblock world, or from no island to an island. + // We don't care if the player is not within an island. + if(!islandCheck.isPresent()) { + return; + } + + World worldFrom = event.getFrom().getWorld(); + World worldTo = event.getTo().getWorld(); + + World overworld = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.NORMAL); + World nether = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.NETHER); + World end = IridiumSkyblock.getInstance().getIslandManager().getWorld(World.Environment.THE_END); + + // We don't care if the player travels within the same world or dimension. + if((worldTo != null) && (worldFrom == worldTo || worldFrom.getEnvironment() == worldTo.getEnvironment())) { + return; + } + + Island island = islandCheck.get(); + int level = island.getLevel(); + Location playerLocation = player.getLocation(); + World destination = worldFrom; + + // ================== + // | NETHER CHECK | + // ================== + + if(event.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) { + // We don't teleport if the Nether is disabled. + if(worldTo == null && nether == null) { + event.setCancelled(true); + player.sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().netherIslandsDisabled + .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) + )); + return; + } + + // We only teleport if the island's level allows it. + if(level < IridiumSkyblock.getInstance().getConfiguration().netherUnlockLevel) { + event.setCancelled(true); + player.sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().netherLocked + .replace("%level%", String.valueOf(IridiumSkyblock.getInstance().getConfiguration().netherUnlockLevel)) + .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) + )); + return; } - }); + + // Set teleport location + destination = Objects.equals(worldFrom, nether) ? overworld : nether; + } + + // =============== + // | END CHECK | + // =============== + + if(event.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL) { + // We don't teleport if the End is disabled. + if(worldTo == null && end == null) { + event.setCancelled(true); + player.sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().endIslandsDisabled + .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) + )); + return; + } + + // We only teleport if the island's level allows it. + if(level < IridiumSkyblock.getInstance().getConfiguration().endUnlockLevel) { + event.setCancelled(true); + player.sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().endLocked + .replace("%level%", String.valueOf(IridiumSkyblock.getInstance().getConfiguration().endUnlockLevel)) + .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) + )); + return; + } + + // Set teleport location + destination = Objects.equals(worldFrom, end) ? overworld : end; + } + + event.setTo(island.getCenter(destination)); + + // Finalize the teleport + Location location = LocationUtils.getSafeLocation(island.getCenter(destination), island); + + if (location == null) { + event.setCancelled(true); + player.sendMessage(StringUtils.color(IridiumSkyblock.getInstance().getMessages().noSafeLocation + .replace("%prefix%", IridiumSkyblock.getInstance().getConfiguration().prefix) + )); + return; + } + + location.setY(location.getY() + 1); + if (XReflection.supports(15)) event.setCanCreatePortal(false); + event.setTo(location); } }