Refactor world info provider; only clamp to logical height when already below

Fixes #4657.
This commit is contained in:
MD 2021-11-30 16:02:49 +00:00
parent 0983167740
commit e35c65b976
9 changed files with 97 additions and 40 deletions

View file

@ -47,6 +47,7 @@ import net.ess3.api.IEssentials;
import net.ess3.api.IItemDb;
import net.ess3.api.IJails;
import net.ess3.api.ISettings;
import net.ess3.nms.refl.providers.ReflDataWorldInfoProvider;
import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider;
import net.ess3.nms.refl.providers.ReflKnownCommandsProvider;
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
@ -81,7 +82,7 @@ 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.ModernDataWorldInfoProvider;
import net.ess3.provider.providers.PaperContainerProvider;
import net.ess3.provider.providers.PaperKnownCommandsProvider;
import net.ess3.provider.providers.PaperMaterialTagProvider;
@ -424,7 +425,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_1_R01)) {
worldInfoProvider = new ModernWorldInfoProvider();
worldInfoProvider = new ModernDataWorldInfoProvider();
} else if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01)) {
worldInfoProvider = new ReflDataWorldInfoProvider();
} else {
worldInfoProvider = new FixedHeightWorldInfoProvider();
}

View file

@ -177,7 +177,7 @@ public class RandomTeleport implements IConf {
final Location location = new Location(
center.getWorld(),
center.getX() + offsetX,
ess.getWorldInfoProvider().getMaxSafeHeight(center.getWorld()),
ess.getWorldInfoProvider().getMaxHeight(center.getWorld()),
center.getZ() + offsetZ,
360 * RANDOM.nextFloat() - 180,
0
@ -195,7 +195,7 @@ 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 < ess.getWorldInfoProvider().getMaxSafeHeight(location.getWorld()); ++y) {
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(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() > ess.getWorldInfoProvider().getMinSafeHeight(location.getWorld()) && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
return location.getBlockY() > ess.getWorldInfoProvider().getMinHeight(location.getWorld()) && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
}
}

View file

@ -22,7 +22,7 @@ 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 unsafe = new Location(user.getWorld(), topX, ess.getWorldInfoProvider().getMaxSafeHeight(user.getWorld()), topZ, yaw, pitch);
final Location unsafe = new Location(user.getWorld(), topX, ess.getWorldInfoProvider().getMaxHeight(user.getWorld()), topZ, yaw, pitch);
final Location safe = LocationUtil.getSafeDestination(ess, unsafe);
final CompletableFuture<Boolean> future = new CompletableFuture<>();
future.thenAccept(success -> {

View file

@ -97,7 +97,7 @@ public final class LocationUtil {
}
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());
return y > ess.getWorldInfoProvider().getMaxHeight(world) || HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType());
}
public static boolean isBlockOutsideWorldBorder(final World world, final int x, final int z) {
@ -203,8 +203,9 @@ public final class LocationUtil {
throw new Exception(tl("destinationNotSet"));
}
final World world = loc.getWorld();
final int worldMinY = ess.getWorldInfoProvider().getMinSafeHeight(world);
final int worldMaxY = ess.getWorldInfoProvider().getMaxSafeHeight(world);
final int worldMinY = ess.getWorldInfoProvider().getMinHeight(world);
final int worldLogicalY = ess.getWorldInfoProvider().getLogicalHeight(world);
final int worldMaxY = loc.getBlockY() < worldLogicalY ? worldLogicalY : ess.getWorldInfoProvider().getMaxHeight(world);
int x = loc.getBlockX();
int y = (int) Math.round(loc.getY());
int z = loc.getBlockZ();

View file

@ -4,18 +4,27 @@ import org.bukkit.World;
public interface WorldInfoProvider extends Provider {
/**
* Gets the maximum safe height for teleportation.
* Gets the maximum height of the world.
*
* @param world The world of which to check the maximum safe height.
* @return The maximum safe height for teleportation
* @param world The world of which to check the maximum height.
* @return The maximum height of the world.
*/
int getMaxSafeHeight(World world);
int getMaxHeight(World world);
/**
* Gets the minimum safe height for teleportation.
* Gets the "logical" height of the world, which is the highest Y level at which vanilla spawns Nether portals and
* performs chorus fruit teleports.
*
* @param world The world of which to check the base height.
* @param world The world of which to check the logical height.
* @return The logical height of the world.
*/
int getLogicalHeight(World world);
/**
* Gets the minimum height of the world.
*
* @param world The world of which to check the minimum height.
* @return The minimum safe height for teleportation
*/
int getMinSafeHeight(World world);
int getMinHeight(World world);
}

View file

@ -6,16 +6,24 @@ import org.bukkit.World;
public class FixedHeightWorldInfoProvider implements WorldInfoProvider {
@Override
public String getDescription() {
return "World info provider for fixed world heights";
return "Fixed world info provider for pre-1.16";
}
@Override
public int getMaxSafeHeight(World world) {
public int getMaxHeight(World world) {
// Method has existed since Beta 1.7 (yes, *beta*)
return world.getMaxHeight();
}
@Override
public int getLogicalHeight(World world) {
// This mirrors the vanilla behaviour up until Minecraft 1.16
return world.getEnvironment() == World.Environment.NETHER ? 128 : 256;
}
@Override
public int getMinSafeHeight(World world) {
public int getMinHeight(World world) {
// Worlds could not go below 0 until Minecraft 1.16
return 0;
}
}

View file

@ -0,0 +1,26 @@
package net.ess3.provider.providers;
import net.ess3.provider.WorldInfoProvider;
import org.bukkit.World;
public class ModernDataWorldInfoProvider implements WorldInfoProvider {
@Override
public String getDescription() {
return "API world info provider for data-driven worldgen for 1.17.1+";
}
@Override
public int getMaxHeight(World world) {
return world.getMaxHeight();
}
@Override
public int getLogicalHeight(World world) {
return world.getLogicalHeight();
}
@Override
public int getMinHeight(World world) {
return world.getMinHeight();
}
}

View file

@ -1,21 +0,0 @@
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();
}
}

View file

@ -0,0 +1,31 @@
package net.ess3.nms.refl.providers;
import net.ess3.provider.WorldInfoProvider;
import org.bukkit.World;
public class ReflDataWorldInfoProvider implements WorldInfoProvider {
@Override
public String getDescription() {
return "NMS world info provider for data-driven worldgen for 1.16.x";
}
@Override
public int getMaxHeight(World world) {
// Method has existed since Beta 1.7 (yes, *beta*)
return world.getMaxHeight();
}
@Override
public int getLogicalHeight(World world) {
// TODO: THIS IS INCORRECT
// This mirrors the vanilla behaviour up until Minecraft 1.16
return world.getEnvironment() == World.Environment.NETHER ? 128 : 256;
}
@Override
public int getMinHeight(World world) {
// TODO: THIS IS INCORRECT
// Worlds could not go below 0 until Minecraft 1.16
return 0;
}
}