From 1509cf8978f187f01f9a090877c019451c168051 Mon Sep 17 00:00:00 2001 From: MD <1917406+mdcfe@users.noreply.github.com> Date: Wed, 24 Nov 2021 04:44:08 +0000 Subject: [PATCH] Support 0>y>256 for safe/random teleports (#4641) Co-authored-by: pop4959 Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com> --- .../earth2me/essentials/AsyncTeleport.java | 2 +- .../com/earth2me/essentials/Essentials.java | 15 ++++++ .../essentials/EssentialsPlayerListener.java | 4 +- .../com/earth2me/essentials/IEssentials.java | 3 ++ .../earth2me/essentials/RandomTeleport.java | 18 ++++---- .../com/earth2me/essentials/SpawnMob.java | 2 +- .../com/earth2me/essentials/Teleport.java | 2 +- .../essentials/commands/Commandsethome.java | 2 +- .../essentials/commands/Commandtop.java | 7 +-- .../essentials/utils/LocationUtil.java | 46 ++++++++++--------- .../net/ess3/provider/WorldInfoProvider.java | 21 +++++++++ .../FixedHeightWorldInfoProvider.java | 21 +++++++++ .../providers/ModernWorldInfoProvider.java | 21 +++++++++ 13 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/WorldInfoProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/providers/FixedHeightWorldInfoProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernWorldInfoProvider.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java index e3026b673..d11c130e7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java @@ -189,7 +189,7 @@ public class AsyncTeleport implements IAsyncTeleport { } PaperLib.getChunkAtAsync(targetLoc.getWorld(), targetLoc.getBlockX() >> 4, targetLoc.getBlockZ() >> 4, true, true).thenAccept(chunk -> { Location loc = targetLoc; - if (LocationUtil.isBlockUnsafeForUser(teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { + if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { if (ess.getSettings().isTeleportSafetyEnabled()) { if (ess.getSettings().isForceDisableTeleportSafety()) { //The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async. diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 4305ed647..b1e6d0241 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -69,16 +69,19 @@ import net.ess3.provider.SpawnEggProvider; import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerItemProvider; import net.ess3.provider.SyncCommandsProvider; +import net.ess3.provider.WorldInfoProvider; import net.ess3.provider.providers.BasePotionDataProvider; import net.ess3.provider.providers.BlockMetaSpawnerItemProvider; import net.ess3.provider.providers.BukkitMaterialTagProvider; import net.ess3.provider.providers.BukkitSpawnerBlockProvider; +import net.ess3.provider.providers.FixedHeightWorldInfoProvider; import net.ess3.provider.providers.FlatSpawnEggProvider; import net.ess3.provider.providers.LegacyItemUnbreakableProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; import net.ess3.provider.providers.ModernItemUnbreakableProvider; import net.ess3.provider.providers.ModernPersistentDataProvider; +import net.ess3.provider.providers.ModernWorldInfoProvider; import net.ess3.provider.providers.PaperContainerProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperMaterialTagProvider; @@ -170,6 +173,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient PersistentDataProvider persistentDataProvider; private transient ReflOnlineModeProvider onlineModeProvider; private transient ItemUnbreakableProvider unbreakableProvider; + private transient WorldInfoProvider worldInfoProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; private transient UpdateChecker updateChecker; @@ -419,6 +423,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { unbreakableProvider = new LegacyItemUnbreakableProvider(); } + if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_1_R01)) { + worldInfoProvider = new ModernWorldInfoProvider(); + } else { + worldInfoProvider = new FixedHeightWorldInfoProvider(); + } + execTimer.mark("Init(Providers)"); reload(); @@ -1284,6 +1294,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { return unbreakableProvider; } + @Override + public WorldInfoProvider getWorldInfoProvider() { + return worldInfoProvider; + } + @Override public PluginCommand getPluginCommand(final String cmd) { return this.getCommand(cmd); diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 8e2dac1fc..0fce2a5bf 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -217,7 +217,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor { to.setY(from.getY()); to.setZ(from.getZ()); try { - event.setTo(LocationUtil.getSafeDestination(to)); + event.setTo(LocationUtil.getSafeDestination(ess, to)); } catch (final Exception ex) { event.setTo(to); } @@ -412,7 +412,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor { if (user.isAuthorized("essentials.fly.safelogin")) { user.getBase().setFallDistance(0); - if (LocationUtil.shouldFly(user.getLocation())) { + if (LocationUtil.shouldFly(ess, user.getLocation())) { user.getBase().setAllowFlight(true); user.getBase().setFlying(true); if (ess.getSettings().isSendFlyEnableOnJoin()) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index 1852eb9b6..cb3df386f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -19,6 +19,7 @@ import net.ess3.provider.SerializationProvider; import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerItemProvider; import net.ess3.provider.SyncCommandsProvider; +import net.ess3.provider.WorldInfoProvider; import net.essentialsx.api.v2.services.BalanceTop; import net.essentialsx.api.v2.services.mail.MailService; import org.bukkit.Server; @@ -162,5 +163,7 @@ public interface IEssentials extends Plugin { ItemUnbreakableProvider getItemUnbreakableProvider(); + WorldInfoProvider getWorldInfoProvider(); + PluginCommand getPluginCommand(String cmd); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java index f48eafd3f..3dfbfd1e0 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java @@ -22,12 +22,12 @@ import java.util.concurrent.ConcurrentLinkedQueue; public class RandomTeleport implements IConf { private static final Random RANDOM = new Random(); private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0; - private final IEssentials essentials; + private final IEssentials ess; private final EssentialsConfiguration config; private final ConcurrentLinkedQueue cachedLocations = new ConcurrentLinkedQueue<>(); public RandomTeleport(final IEssentials essentials) { - this.essentials = essentials; + this.ess = essentials; config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml", "Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game."); reloadConfig(); @@ -47,8 +47,8 @@ public class RandomTeleport implements IConf { } } catch (final InvalidWorldException ignored) { } - final Location center = essentials.getServer().getWorlds().get(0).getWorldBorder().getCenter(); - center.setY(center.getWorld().getHighestBlockYAt(center) + 1); + final Location center = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter(); + center.setY(center.getWorld().getHighestBlockYAt(center) + HIGHEST_BLOCK_Y_OFFSET); setCenter(center); return center; } @@ -124,7 +124,7 @@ public class RandomTeleport implements IConf { // Prompts caching random valid locations, up to a maximum number of attempts public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) { - essentials.getServer().getScheduler().scheduleSyncDelayedTask(essentials, () -> { + ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> { for (int i = 0; i < this.getFindAttempts(); ++i) { calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> { if (isValidRandomLocation(location)) { @@ -177,7 +177,7 @@ public class RandomTeleport implements IConf { final Location location = new Location( center.getWorld(), center.getX() + offsetX, - center.getWorld().getMaxHeight(), + ess.getWorldInfoProvider().getMaxSafeHeight(center.getWorld()), center.getZ() + offsetZ, 360 * RANDOM.nextFloat() - 180, 0 @@ -195,8 +195,8 @@ public class RandomTeleport implements IConf { // Returns an appropriate elevation for a given location in the nether, or -1 if none is found private double getNetherYAt(final Location location) { - for (int y = 32; y < location.getWorld().getMaxHeight() / 2; ++y) { - if (!LocationUtil.isBlockUnsafe(location.getWorld(), location.getBlockX(), y, location.getBlockZ())) { + for (int y = 32; y < ess.getWorldInfoProvider().getMaxSafeHeight(location.getWorld()); ++y) { + if (!LocationUtil.isBlockUnsafe(ess, location.getWorld(), location.getBlockX(), y, location.getBlockZ())) { return y; } } @@ -204,6 +204,6 @@ public class RandomTeleport implements IConf { } private boolean isValidRandomLocation(final Location location) { - return location.getBlockY() > 0 && !this.getExcludedBiomes().contains(location.getBlock().getBiome()); + return location.getBlockY() > ess.getWorldInfoProvider().getMinSafeHeight(location.getWorld()) && !this.getExcludedBiomes().contains(location.getBlock().getBiome()); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/SpawnMob.java b/Essentials/src/main/java/com/earth2me/essentials/SpawnMob.java index 7fa39ab57..a983b016e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/SpawnMob.java +++ b/Essentials/src/main/java/com/earth2me/essentials/SpawnMob.java @@ -103,7 +103,7 @@ public final class SpawnMob { // This method spawns a mob at loc, owned by target public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location loc, final List parts, final List data, int mobCount) throws Exception { - final Location sloc = LocationUtil.getSafeDestination(loc); + final Location sloc = LocationUtil.getSafeDestination(ess, loc); for (final String part : parts) { final Mob mob = Mob.fromName(part); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Teleport.java b/Essentials/src/main/java/com/earth2me/essentials/Teleport.java index d98488210..6038b2e35 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Teleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Teleport.java @@ -145,7 +145,7 @@ public class Teleport implements ITeleport { teleportee.getBase().eject(); } - if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { + if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { if (ess.getSettings().isTeleportSafetyEnabled()) { if (ess.getSettings().isForceDisableTeleportSafety()) { PaperLib.teleportAsync(teleportee.getBase(), loc, cause); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsethome.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsethome.java index 94626cec6..15f29dc0c 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsethome.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsethome.java @@ -51,7 +51,7 @@ public class Commandsethome extends EssentialsCommand { } final Location location = user.getLocation(); - if ((!ess.getSettings().isTeleportSafetyEnabled() || !ess.getSettings().isForceDisableTeleportSafety()) && LocationUtil.isBlockUnsafeForUser(usersHome, location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ())) { + if ((!ess.getSettings().isTeleportSafetyEnabled() || !ess.getSettings().isForceDisableTeleportSafety()) && LocationUtil.isBlockUnsafeForUser(ess, usersHome, location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ())) { throw new Exception(tl("unsafeTeleportDestination", location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ())); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtop.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtop.java index 18b621170..60b7f53d9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtop.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtop.java @@ -22,13 +22,14 @@ public class Commandtop extends EssentialsCommand { final int topZ = user.getLocation().getBlockZ(); final float pitch = user.getLocation().getPitch(); final float yaw = user.getLocation().getYaw(); - final Location loc = LocationUtil.getSafeDestination(new Location(user.getWorld(), topX, user.getWorld().getMaxHeight(), topZ, yaw, pitch)); + final Location unsafe = new Location(user.getWorld(), topX, ess.getWorldInfoProvider().getMaxSafeHeight(user.getWorld()), topZ, yaw, pitch); + final Location safe = LocationUtil.getSafeDestination(ess, unsafe); final CompletableFuture future = new CompletableFuture<>(); future.thenAccept(success -> { if (success) { - user.sendMessage(tl("teleportTop", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + user.sendMessage(tl("teleportTop", safe.getWorld().getName(), safe.getBlockX(), safe.getBlockY(), safe.getBlockZ())); } }); - user.getAsyncTeleport().teleport(loc, new Trade(this.getName(), ess), TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel)); + user.getAsyncTeleport().teleport(safe, new Trade(this.getName(), ess), TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel)); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/LocationUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/LocationUtil.java index 06ad564f1..e9ea72440 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/LocationUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/LocationUtil.java @@ -1,6 +1,7 @@ package com.earth2me.essentials.utils; import com.earth2me.essentials.IEssentials; +import com.google.common.primitives.Ints; import net.ess3.api.IUser; import org.bukkit.GameMode; import org.bukkit.Location; @@ -95,8 +96,8 @@ public final class LocationUtil { return block.getLocation(); } - public static boolean isBlockAboveAir(final World world, final int x, final int y, final int z) { - return y > world.getMaxHeight() || HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType()); + public static boolean isBlockAboveAir(IEssentials ess, final World world, final int x, final int y, final int z) { + return y > ess.getWorldInfoProvider().getMaxSafeHeight(world) || HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType()); } public static boolean isBlockOutsideWorldBorder(final World world, final int x, final int z) { @@ -131,7 +132,7 @@ public final class LocationUtil { return z; } - public static boolean isBlockUnsafeForUser(final IUser user, final World world, final int x, final int y, final int z) { + public static boolean isBlockUnsafeForUser(IEssentials ess, final IUser user, final World world, final int x, final int y, final int z) { if (user.getBase().isOnline() && world.equals(user.getBase().getWorld()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.getBase().getGameMode() == GameMode.SPECTATOR || user.isGodModeEnabled()) && user.getBase().getAllowFlight()) { return false; } @@ -139,14 +140,14 @@ public final class LocationUtil { if (isBlockDamaging(world, x, y, z)) { return true; } - if (isBlockAboveAir(world, x, y, z)) { + if (isBlockAboveAir(ess, world, x, y, z)) { return true; } return isBlockOutsideWorldBorder(world, x, z); } - public static boolean isBlockUnsafe(final World world, final int x, final int y, final int z) { - return isBlockDamaging(world, x, y, z) || isBlockAboveAir(world, x, y, z); + public static boolean isBlockUnsafe(IEssentials ess, final World world, final int x, final int y, final int z) { + return isBlockDamaging(world, x, y, z) || isBlockAboveAir(ess, world, x, y, z); } public static boolean isBlockDamaging(final World world, final int x, final int y, final int z) { @@ -184,7 +185,7 @@ public final class LocationUtil { public static Location getSafeDestination(final IEssentials ess, final IUser user, final Location loc) throws Exception { if (user.getBase().isOnline() && (ess == null || !ess.getSettings().isAlwaysTeleportSafety()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.getBase().getGameMode() == GameMode.SPECTATOR || user.isGodModeEnabled())) { - if (shouldFly(loc) && user.getBase().getAllowFlight()) { + if (shouldFly(ess, loc) && user.getBase().getAllowFlight()) { user.getBase().setFlying(true); } // ess can be null if old deprecated method is calling it. @@ -194,14 +195,16 @@ public final class LocationUtil { return loc; } } - return getSafeDestination(loc); + return getSafeDestination(ess, loc); } - public static Location getSafeDestination(final Location loc) throws Exception { + public static Location getSafeDestination(IEssentials ess, final Location loc) throws Exception { if (loc == null || loc.getWorld() == null) { throw new Exception(tl("destinationNotSet")); } final World world = loc.getWorld(); + final int worldMinY = ess.getWorldInfoProvider().getMinSafeHeight(world); + final int worldMaxY = ess.getWorldInfoProvider().getMaxSafeHeight(world); int x = loc.getBlockX(); int y = (int) Math.round(loc.getY()); int z = loc.getBlockZ(); @@ -212,42 +215,43 @@ public final class LocationUtil { final int origX = x; final int origY = y; final int origZ = z; - while (isBlockAboveAir(world, x, y, z)) { + while (isBlockAboveAir(ess, world, x, y, z)) { y -= 1; if (y < 0) { y = origY; break; } } - if (isBlockUnsafe(world, x, y, z)) { + if (isBlockUnsafe(ess, world, x, y, z)) { x = Math.round(loc.getX()) == origX ? x - 1 : x + 1; z = Math.round(loc.getZ()) == origZ ? z - 1 : z + 1; } int i = 0; - while (isBlockUnsafe(world, x, y, z)) { + while (isBlockUnsafe(ess, world, x, y, z)) { i++; if (i >= VOLUME.length) { x = origX; - y = origY + RADIUS; + y = Ints.constrainToRange(origY + RADIUS, worldMinY, worldMaxY); z = origZ; break; } x = origX + VOLUME[i].x; - y = origY + VOLUME[i].y; + y = Ints.constrainToRange(origY + VOLUME[i].y, worldMinY, worldMaxY); z = origZ + VOLUME[i].z; } - while (isBlockUnsafe(world, x, y, z)) { + while (isBlockUnsafe(ess, world, x, y, z)) { y += 1; - if (y >= world.getMaxHeight()) { + if (y >= worldMaxY) { x += 1; break; } } - while (isBlockUnsafe(world, x, y, z)) { + while (isBlockUnsafe(ess, world, x, y, z)) { y -= 1; - if (y <= 1) { + if (y <= worldMinY + 1) { x += 1; - y = world.getHighestBlockYAt(x, z); + // Allow spawning at the top of the world, but not above the nether roof + y = Math.min(world.getHighestBlockYAt(x, z) + 1, worldMaxY); if (x - 48 > loc.getBlockX()) { throw new Exception(tl("holeInFloor")); } @@ -256,13 +260,13 @@ public final class LocationUtil { return new Location(world, x + 0.5, y, z + 0.5, loc.getYaw(), loc.getPitch()); } - public static boolean shouldFly(final Location loc) { + public static boolean shouldFly(IEssentials ess, final Location loc) { final World world = loc.getWorld(); final int x = loc.getBlockX(); int y = (int) Math.round(loc.getY()); final int z = loc.getBlockZ(); int count = 0; - while (LocationUtil.isBlockUnsafe(world, x, y, z) && y > -1) { + while (LocationUtil.isBlockUnsafe(ess, world, x, y, z) && y > -1) { y--; count++; if (count > 2) { diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/WorldInfoProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/WorldInfoProvider.java new file mode 100644 index 000000000..b1f4034d4 --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/WorldInfoProvider.java @@ -0,0 +1,21 @@ +package net.ess3.provider; + +import org.bukkit.World; + +public interface WorldInfoProvider extends Provider { + /** + * Gets the maximum safe height for teleportation. + * + * @param world The world of which to check the maximum safe height. + * @return The maximum safe height for teleportation + */ + int getMaxSafeHeight(World world); + + /** + * Gets the minimum safe height for teleportation. + * + * @param world The world of which to check the base height. + * @return The minimum safe height for teleportation + */ + int getMinSafeHeight(World world); +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/FixedHeightWorldInfoProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/FixedHeightWorldInfoProvider.java new file mode 100644 index 000000000..80a34f85b --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/FixedHeightWorldInfoProvider.java @@ -0,0 +1,21 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.WorldInfoProvider; +import org.bukkit.World; + +public class FixedHeightWorldInfoProvider implements WorldInfoProvider { + @Override + public String getDescription() { + return "World info provider for fixed world heights"; + } + + @Override + public int getMaxSafeHeight(World world) { + return world.getEnvironment() == World.Environment.NETHER ? 128 : 256; + } + + @Override + public int getMinSafeHeight(World world) { + return 0; + } +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernWorldInfoProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernWorldInfoProvider.java new file mode 100644 index 000000000..634eb8345 --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernWorldInfoProvider.java @@ -0,0 +1,21 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.WorldInfoProvider; +import org.bukkit.World; + +public class ModernWorldInfoProvider implements WorldInfoProvider { + @Override + public String getDescription() { + return "World info provider for data-driven world generation"; + } + + @Override + public int getMaxSafeHeight(World world) { + return world.getLogicalHeight(); + } + + @Override + public int getMinSafeHeight(World world) { + return world.getMinHeight(); + } +}