Merge pull request #3151 from Multiverse/ben/mv5/block-safety

ben/mv5/block-safety
This commit is contained in:
Ben Woo 2025-01-16 09:50:31 +08:00 committed by GitHub
commit 3a9eb88197
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 464 additions and 28 deletions

View File

@ -10,6 +10,7 @@ import org.jvnet.hk2.annotations.Contract;
/**
* Used to get block/location-related information.
*/
@Deprecated
@Contract
public interface BlockSafety {
/**

View File

@ -112,6 +112,14 @@ public interface MVConfig {
*/
void setFirstSpawnOverride(boolean firstSpawnOverride);
void setSafeLocationHorizontalSearchRadius(int searchRadius);
int getSafeLocationHorizontalSearchRadius();
void setSafeLocationVerticalSearchRadius(int searchRadius);
int getSafeLocationVerticalSearchRadius();
/**
* Gets firstSpawnOverride.
* @return firstSpawnOverride.

View File

@ -189,6 +189,26 @@ public class MVCoreConfig implements MVConfig {
configHandle.set(configNodes.FIRST_SPAWN_OVERRIDE, firstSpawnOverride);
}
@Override
public void setSafeLocationHorizontalSearchRadius(int searchRadius) {
configHandle.set(configNodes.SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS, searchRadius);
}
@Override
public int getSafeLocationHorizontalSearchRadius() {
return configHandle.get(configNodes.SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS);
}
@Override
public void setSafeLocationVerticalSearchRadius(int searchRadius) {
configHandle.set(configNodes.SAFE_LOCATION_VERTICAL_SEARCH_RADIUS, searchRadius);
}
@Override
public int getSafeLocationVerticalSearchRadius() {
return configHandle.get(configNodes.SAFE_LOCATION_VERTICAL_SEARCH_RADIUS);
}
@Override
public boolean getFirstSpawnOverride() {
return configHandle.get(configNodes.FIRST_SPAWN_OVERRIDE);

View File

@ -130,6 +130,24 @@ class MVCoreConfigNodes {
.name("teleport-intercept")
.build());
final ConfigNode<Integer> SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS = node(ConfigNode.builder("teleport.safe-location-horizontal-search-radius", Integer.class)
.comment("")
.comment("Sets the horizontal (x and z-axis) search radius for finding a safe location to teleport to.")
.comment("Increasing this value will widen the search area at the cost of performance.")
.comment("To disable, set to 0.")
.defaultValue(3)
.name("safe-location-horizontal-search-radius")
.build());
final ConfigNode<Integer> SAFE_LOCATION_VERTICAL_SEARCH_RADIUS = node(ConfigNode.builder("teleport.safe-location-vertical-search-radius", Integer.class)
.comment("")
.comment("Sets the vertical (y-axis) search radius for finding a safe location to teleport to.")
.comment("Increasing this value will widen the search area at the cost of performance.")
.comment("To disable, set to 0.")
.defaultValue(3)
.name("safe-location-vertical-search-radius")
.build());
private final ConfigHeaderNode SPAWN_HEADER = node(ConfigHeaderNode.builder("spawn")
.comment("")
.comment("")

View File

@ -8,7 +8,6 @@
package org.mvplugins.multiverse.core.listeners;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import com.dumptruckman.minecraft.util.Logging;
@ -24,22 +23,20 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.MultiverseCore;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
import org.mvplugins.multiverse.core.config.MVCoreConfig;
import org.mvplugins.multiverse.core.destination.DestinationInstance;
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
import org.mvplugins.multiverse.core.economy.MVEconomist;
import org.mvplugins.multiverse.core.event.MVRespawnEvent;
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter;
import org.mvplugins.multiverse.core.teleportation.TeleportQueue;
import org.mvplugins.multiverse.core.utils.result.ResultChain;
@ -58,7 +55,7 @@ public class MVPlayerListener implements CoreListener {
private final Plugin plugin;
private final MVCoreConfig config;
private final Provider<WorldManager> worldManagerProvider;
private final BlockSafety blockSafety;
private final AdvancedBlockSafety blockSafety;
private final AsyncSafetyTeleporter safetyTeleporter;
private final Server server;
private final TeleportQueue teleportQueue;
@ -75,7 +72,7 @@ public class MVPlayerListener implements CoreListener {
MultiverseCore plugin,
MVCoreConfig config,
Provider<WorldManager> worldManagerProvider,
BlockSafety blockSafety,
AdvancedBlockSafety blockSafety,
AsyncSafetyTeleporter safetyTeleporter,
Server server,
TeleportQueue teleportQueue,
@ -317,6 +314,7 @@ public class MVPlayerListener implements CoreListener {
return;
}
}
/**
* This method is called when a player actually portals via a vanilla style portal.
* @param event The Event that was fired.

View File

@ -0,0 +1,394 @@
package org.mvplugins.multiverse.core.teleportation;
import com.dumptruckman.minecraft.util.Logging;
import io.vavr.control.Option;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Rail;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.api.LocationManipulation;
import org.mvplugins.multiverse.core.config.MVCoreConfig;
/**
* Used to check get or find block/location-related information.
*/
@Service
public class AdvancedBlockSafety {
private final MVCoreConfig config;
private final LocationManipulation locationManipulation;
@Inject
AdvancedBlockSafety(@NotNull MVCoreConfig config, @NotNull LocationManipulation locationManipulation) {
this.config = config;
this.locationManipulation = locationManipulation;
}
/**
* Function to check if a block is above air.
*
* @param location The location to check.
* @return True if the block at that {@link Location} is above air.
*/
public boolean isBlockAboveAir(Location location) {
return location.getBlock().getRelative(0, -1, 0).getType().isAir();
}
/**
* Checks if an entity would be on track at the specified {@link Location}.
*
* @param location The location to check.
* @return True if an entity would be on tracks at the specified {@link Location}.
*/
public boolean isEntityOnTrack(Location location) {
return location.getBlock().getBlockData() instanceof Rail;
}
/**
* Gets the location of the highest spawnable block (i.e. y-axis) at the specified {@link Location}.
*
* @param location The location
* @return The location if found, null of all blocks are unsafe.
*/
public Location getTopBlock(Location location) {
Location check = location.clone();
int maxHeight = Option.of(location.getWorld()).map(World::getMaxHeight).getOrElse(127);
check.setY(maxHeight);
while (check.getY() > 0) {
if (canSpawnAtLocationSafely(check)) {
return check;
}
check.setY(check.getY() - 1);
}
return null;
}
/**
* Gets the location of the lowest spawnable block (i.e. y-axis) at the specified {@link Location}.
*
* @param location The location
* @return The location if found, null of all blocks are unsafe.
*/
public Location getBottomBlock(Location location) {
Location check = location.clone();
int minHeight = Option.of(location.getWorld()).map(World::getMinHeight).getOrElse(0);
check.setY(minHeight);
while (check.getY() < 127) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
if (canSpawnAtLocationSafely(check)) {
return check;
}
check.setY(check.getY() + 1);
}
return null;
}
/**
* Checks if the specified {@link Minecart} can spawn safely.
*
* @param cart The {@link Minecart}.
* @return True if the minecart can spawn safely.
*/
public boolean canSpawnCartSafely(Minecart cart) {
if (isBlockAboveAir(cart.getLocation())) {
return true;
}
return isEntityOnTrack(locationManipulation.getNextBlock(cart));
}
/**
* Checks if the specified {@link Vehicle} can spawn safely.
*
* @param vehicle The {@link Vehicle}.
* @return True if the vehicle can spawn safely.
*/
public boolean canSpawnVehicleSafely(Vehicle vehicle) {
return isBlockAboveAir(vehicle.getLocation());
}
/**
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
* etc. This also ensures there is enough space for a player to spawn!
*
* @param location The {@link Location}
* @return Whether the player can spawn safely at the given {@link Location}
*/
public boolean canSpawnAtLocationSafely(@NotNull Location location) {
return canSpawnAtBlockSafely(location.getBlock());
}
/**
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
* etc. This also ensures there is enough space for a player to spawn!
*
* @param block The {@link Block}
* @return Whether the player can spawn safely at the given {@link Location}
*/
public boolean canSpawnAtBlockSafely(@NotNull Block block) {
Logging.finest("Checking spawn safety for location: %s, %s, %s", block.getX(), block.getY(), block.getZ());
if (isUnsafeSpawnBody(block)) {
// Player body will be stuck in solid
Logging.finest("Unsafe location for player's body.");
return false;
}
Block airBlockForHead = block.getRelative(0, 1, 0);
if (isUnsafeSpawnBody(airBlockForHead)) {
// Player's head will be stuck in solid
Logging.finest("Unsafe location for player's head.");
return false;
}
Block standingOnBlock = block.getRelative(0, -1, 0);
if (isUnsafeSpawnPlatform(standingOnBlock)) {
// Player will drop down
Logging.finest("Unsafe location due to invalid platform.");
return false;
}
Logging.finest("Location is safe.");
return true;
}
/**
* Player's body must be in non-solid block that is non-harming.
*
* @param block The block
* @return True if the block is unsafe
*/
private boolean isUnsafeSpawnBody(@NotNull Block block) {
Material blockMaterial = block.getType();
return blockMaterial.isSolid() || blockMaterial == Material.FIRE;
}
/**
* Player must stand on solid ground, or water that is only 1 block deep to prevent drowning.
*
* @param block The block
* @return True if the block is unsafe
*/
private boolean isUnsafeSpawnPlatform(@NotNull Block block) {
return !block.getType().isSolid() || isDeepWater(block);
}
/**
* Water that is 2 or more block deep
*
* @param block The block
* @return True if the block is unsafe
*/
private boolean isDeepWater(@NotNull Block block) {
if (block.getType() != Material.WATER) {
return false;
}
return block.getRelative(0, -1, 0).getType() == Material.WATER;
}
/**
* Finds the closest possible safe location around the given location with the configured search radius.
*
* @param location The target location to find
* @return The safe location if found, otherwise null.
*/
@Nullable
public Location findSafeSpawnLocation(@NotNull Location location) {
return findSafeSpawnLocation(
location,
config.getSafeLocationHorizontalSearchRadius(),
config.getSafeLocationVerticalSearchRadius());
}
/**
* Finds the closest possible safe location around the given location.
*
* @param location The target location to find
* @param horizontalRange The radius around x,z of given location to search.
* @param verticalRange The height of how far up and down to search.
* @return The safe location if found, otherwise null.
*/
@Nullable
public Location findSafeSpawnLocation(@NotNull Location location, int horizontalRange, int verticalRange) {
Block safeBlock = findSafeSpawnBlock(location.getBlock(), horizontalRange, verticalRange);
if (safeBlock == null) {
return null;
}
return new Location(
location.getWorld(),
safeBlock.getX() + 0.5,
safeBlock.getY(),
safeBlock.getZ() + 0.5,
location.getYaw(),
location.getPitch());
}
/**
* Finds the closest possible location around the given block with the configured search radius.
*
* @param block The target block to find
* @return The safe block if found, otherwise null.
*/
@Nullable
public Block findSafeSpawnBlock(@NotNull Block block) {
return findSafeSpawnBlock(
block,
config.getSafeLocationHorizontalSearchRadius(),
config.getSafeLocationVerticalSearchRadius());
}
/**
* Finds the closest possible location around the given block.
*
* @param block The target block to find
* @param horizontalRange The radius around x,z of given block to search.
* @param verticalRange The height of how far up and down to search.
* @return The safe block if found, otherwise null.
*/
@Nullable
public Block findSafeSpawnBlock(@NotNull Block block, int horizontalRange, int verticalRange) {
Block searchResult = searchAroundXZ(block, horizontalRange);
if (searchResult != null) {
return searchResult;
}
int maxHeight = block.getWorld().getMaxHeight();
int minHeight = block.getWorld().getMinHeight();
for (int i = 1; i <= verticalRange; i++) {
if (block.getY() + i < maxHeight) {
searchResult = searchAroundXZ(block.getRelative(0, i, 0), horizontalRange);
if (searchResult != null) {
return searchResult;
}
}
if (block.getY() - i >= minHeight) {
searchResult = searchAroundXZ(block.getRelative(0, -i, 0), horizontalRange);
if (searchResult != null) {
return searchResult;
}
}
}
return null;
}
/**
* Search a square from n - radius to n + radius for both x and z
*
* @param block The block to be relative to
* @param radius The number of blocks +/- x and z to search
* @return The safe block, or null
*/
@Nullable
private Block searchAroundXZ(Block block, int radius) {
if (canSpawnAtBlockSafely(block)) {
return block;
}
for (int r = 1; r <= radius; r++) {
boolean radiusX = true;
boolean incrementOffset = false;
int offset = 0;
int noOfIterations = r * 2 + 1;
for (int i = 0; i < noOfIterations; i++) {
Block searchResult = radiusX
? searchPlusMinusPermutation(block, r, offset)
: searchPlusMinusPermutation(block, offset, r);
if (searchResult != null) {
return searchResult;
}
if (incrementOffset) {
offset++;
}
radiusX = !radiusX;
incrementOffset = !incrementOffset;
}
}
return null;
}
/**
* Search 4 relative blocks with the following offsets: (-x, -z) (-x, z) (x, -z) (x, z)
*
* @param block The block to be relative to
* @param x Amount to offset for the x axis
* @param z Amount to offset for the z axis
* @return The safe block, or null
*/
@Nullable
private Block searchPlusMinusPermutation(Block block, int x, int z) {
Block relative = block.getRelative(-x, 0, -z);
if (canSpawnAtBlockSafely(relative)) {
return relative;
}
if (z != 0) {
relative = block.getRelative(-x, 0, z);
if (canSpawnAtBlockSafely(relative)) {
return relative;
}
}
if (x != 0) {
relative = block.getRelative(x, 0, -z);
if (canSpawnAtBlockSafely(relative)) {
return relative;
}
if (z != 0) {
relative = block.getRelative(x, 0, z);
if (canSpawnAtBlockSafely(relative)) {
return relative;
}
}
}
return null;
}
/**
* Finds a portal-block next to the specified {@link Location}.
*
* @param location The {@link Location}
* @return The next portal-block's {@link Location} if found, otherwise null.
*/
@Nullable
public Location findPortalBlockNextTo(Location location) {
if (location.getWorld() == null) {
return null;
}
Block b = location.getWorld().getBlockAt(location);
Location foundLocation = null;
if (b.getType() == Material.NETHER_PORTAL) {
return location;
}
if (b.getRelative(BlockFace.NORTH).getType() == Material.NETHER_PORTAL) {
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.NORTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.SOUTH).getType() == Material.NETHER_PORTAL) {
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.SOUTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.EAST).getType() == Material.NETHER_PORTAL) {
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.EAST).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.WEST).getType() == Material.NETHER_PORTAL) {
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.WEST).getLocation(), foundLocation);
}
return foundLocation;
}
private Location getCloserBlock(Location source, Location blockA, Location blockB) {
// If B wasn't given, return a.
if (blockB == null) {
return blockA;
}
// Center our calculations
blockA.add(.5, 0, .5);
blockB.add(.5, 0, .5);
// Retrieve the distance to the normalized blocks
double testA = source.distance(blockA);
double testB = source.distance(blockB);
// Compare and return
if (testA <= testB) {
return blockA;
}
return blockB;
}
}

View File

@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.destination.DestinationInstance;
/**
@ -16,13 +15,13 @@ import org.mvplugins.multiverse.core.destination.DestinationInstance;
*/
@Service
public class AsyncSafetyTeleporter {
private final BlockSafety blockSafety;
private final AdvancedBlockSafety blockSafety;
private final TeleportQueue teleportQueue;
private final PluginManager pluginManager;
@Inject
AsyncSafetyTeleporter(
@NotNull BlockSafety blockSafety,
@NotNull AdvancedBlockSafety blockSafety,
@NotNull TeleportQueue teleportQueue,
@NotNull PluginManager pluginManager) {
this.blockSafety = blockSafety;

View File

@ -11,7 +11,6 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.destination.DestinationInstance;
import org.mvplugins.multiverse.core.event.MVTeleportDestinationEvent;
import org.mvplugins.multiverse.core.utils.result.Async;
@ -25,7 +24,7 @@ import java.util.List;
*/
public class AsyncSafetyTeleporterAction {
private final BlockSafety blockSafety;
private final AdvancedBlockSafety blockSafety;
private final TeleportQueue teleportQueue;
private final PluginManager pluginManager;
@ -34,7 +33,7 @@ public class AsyncSafetyTeleporterAction {
private @Nullable CommandSender teleporter = null;
AsyncSafetyTeleporterAction(
@NotNull BlockSafety blockSafety,
@NotNull AdvancedBlockSafety blockSafety,
@NotNull TeleportQueue teleportQueue,
@NotNull PluginManager pluginManager,
@NotNull Either<Location, DestinationInstance<?, ?>> locationOrDestination) {
@ -146,7 +145,7 @@ public class AsyncSafetyTeleporterAction {
if (!this.checkSafety) {
return Attempt.success(location);
}
Location safeLocation = blockSafety.getSafeLocation(location);
Location safeLocation = blockSafety.findSafeSpawnLocation(location);
if (safeLocation == null) {
return Attempt.failure(TeleportFailureReason.UNSAFE_LOCATION);
}

View File

@ -21,7 +21,6 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Bed;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@ -31,6 +30,7 @@ import org.mvplugins.multiverse.core.api.LocationManipulation;
/**
* The default-implementation of {@link BlockSafety}.
*/
@Deprecated
@Service
public class SimpleBlockSafety implements BlockSafety {
private static final int DEFAULT_TOLERANCE = 6;

View File

@ -13,8 +13,8 @@ import org.bukkit.entity.Player;
import org.bukkit.generator.BiomeProvider;
import org.jetbrains.annotations.NotNull;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.api.LocationManipulation;
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
import org.mvplugins.multiverse.core.world.config.NullLocation;
import org.mvplugins.multiverse.core.world.config.SpawnLocation;
import org.mvplugins.multiverse.core.world.config.WorldConfig;
@ -23,18 +23,16 @@ import org.mvplugins.multiverse.core.world.config.WorldConfig;
* Extension of {@link MultiverseWorld} that represents a world that is currently loaded with bukkit world object.
*/
public class LoadedMultiverseWorld extends MultiverseWorld {
private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
private final UUID worldUid;
private final BlockSafety blockSafety;
private final AdvancedBlockSafety blockSafety;
private final LocationManipulation locationManipulation;
LoadedMultiverseWorld(
@NotNull World world,
@NotNull WorldConfig worldConfig,
@NotNull BlockSafety blockSafety,
@NotNull AdvancedBlockSafety blockSafety,
@NotNull LocationManipulation locationManipulation) {
super(world.getName(), worldConfig);
this.worldUid = world.getUID();
@ -68,7 +66,7 @@ public class LoadedMultiverseWorld extends MultiverseWorld {
Location location = world.getSpawnLocation();
// Verify that location was safe
if (blockSafety.playerCanSpawnHereSafely(location)) {
if (blockSafety.canSpawnAtLocationSafely(location)) {
return location;
}
@ -83,8 +81,7 @@ public class LoadedMultiverseWorld extends MultiverseWorld {
// The location is not safe, so we need to find a better one.
Logging.warning("Spawn location from world.dat file was unsafe. Adjusting...");
Logging.warning("Original Location: " + locationManipulation.strCoordsRaw(location));
Location newSpawn = blockSafety.getSafeLocation(location,
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
Location newSpawn = blockSafety.findSafeSpawnLocation(location);
// I think we could also do this, as I think this is what Notch does.
// Not sure how it will work in the nether...
//Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();

View File

@ -27,9 +27,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.api.LocationManipulation;
import org.mvplugins.multiverse.core.event.MVWorldDeleteEvent;
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
import org.mvplugins.multiverse.core.utils.message.MessageReplacement;
import org.mvplugins.multiverse.core.utils.result.Attempt;
import org.mvplugins.multiverse.core.utils.result.FailureReason;
@ -76,7 +76,7 @@ public class WorldManager {
private final GeneratorProvider generatorProvider;
private final PlayerWorldTeleporter playerWorldActions;
private final FilesManipulator filesManipulator;
private final BlockSafety blockSafety;
private final AdvancedBlockSafety blockSafety;
private final LocationManipulation locationManipulation;
private final PluginManager pluginManager;
@ -87,7 +87,7 @@ public class WorldManager {
@NotNull GeneratorProvider generatorProvider,
@NotNull PlayerWorldTeleporter playerWorldActions,
@NotNull FilesManipulator filesManipulator,
@NotNull BlockSafety blockSafety,
@NotNull AdvancedBlockSafety blockSafety,
@NotNull LocationManipulation locationManipulation,
@NotNull PluginManager pluginManager) {
this.pluginManager = pluginManager;

View File

@ -10,6 +10,7 @@ import org.mvplugins.multiverse.core.config.MVCoreConfig
import org.mvplugins.multiverse.core.destination.Destination
import org.mvplugins.multiverse.core.economy.MVEconomist
import org.mvplugins.multiverse.core.listeners.*
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter
import org.mvplugins.multiverse.core.teleportation.SimpleBlockSafety
import org.mvplugins.multiverse.core.teleportation.SimpleLocationManipulation
@ -34,9 +35,8 @@ class InjectionTest : TestWithMockBukkit() {
}
@Test
fun `BlockSafety is available as a service`() {
assertNotNull(serviceLocator.getActiveService(BlockSafety::class.java))
assertNotNull(serviceLocator.getActiveService(SimpleBlockSafety::class.java))
fun `AdvancedBlockSafety is available as a service`() {
assertNotNull(serviceLocator.getActiveService(AdvancedBlockSafety::class.java))
}
@Test

View File

@ -7,6 +7,8 @@ teleport:
use-finer-teleport-permissions: true
concurrent-teleport-limit: 50
teleport-intercept: true
safe-location-horizontal-search-radius: 3
safe-location-vertical-search-radius: 3
spawn:
first-spawn-override: true