warn at out-of-bounds access rather than crash on Bukkit.

This commit is contained in:
dfsek
2021-12-19 13:48:51 -07:00
parent 77d341ebab
commit 30f7f002d5
4 changed files with 49 additions and 14 deletions

View File

@@ -208,6 +208,6 @@ public class TerraBukkitPlugin extends JavaPlugin {
ConfigPack pack = platform.getConfigRegistry().get(id).orElseThrow(
() -> new IllegalArgumentException("No such config pack \"" + id + "\""));
return pack.getGeneratorProvider().newInstance(pack);
}), platform.getRawConfigRegistry().get(id).orElseThrow());
}), platform.getRawConfigRegistry().get(id).orElseThrow(), platform.getWorldHandle().air());
}
}

View File

@@ -17,6 +17,8 @@
package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.block.state.BlockState;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.generator.BiomeProvider;
@@ -41,12 +43,14 @@ import com.dfsek.terra.bukkit.world.BukkitServerWorld;
public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGenerator implements GeneratorWrapper {
private final ChunkGenerator delegate;
private final ConfigPack pack;
private final BlockState air;
private World world;
private ServerWorld terraWorld;
public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack) {
public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack, BlockState air) {
this.delegate = delegate;
this.pack = pack;
this.air = air;
}
@Override
@@ -71,7 +75,7 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
@Override
public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z,
@NotNull LimitedRegion limitedRegion) {
generationStage.populate(new BukkitProtoWorld(limitedRegion));
generationStage.populate(new BukkitProtoWorld(limitedRegion, air));
}
})
.collect(Collectors.toList());

View File

@@ -18,11 +18,22 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
import com.dfsek.terra.bukkit.world.block.state.BukkitBlockEntity;
import com.dfsek.terra.bukkit.world.entity.BukkitEntityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import java.util.function.Supplier;
public class BukkitProtoWorld implements ProtoWorld {
private final LimitedRegion delegate;
private final BlockState air;
private static final Logger LOGGER = LoggerFactory.getLogger(BukkitProtoWorld.class);
public BukkitProtoWorld(LimitedRegion delegate) { this.delegate = delegate; }
public BukkitProtoWorld(LimitedRegion delegate, BlockState air) {
this.delegate = delegate;
this.air = air;
}
@Override
public LimitedRegion getHandle() {
@@ -31,10 +42,12 @@ public class BukkitProtoWorld implements ProtoWorld {
@Override
public void setBlockState(int x, int y, int z, BlockState data, boolean physics) {
delegate.setBlockData(x, y, z, BukkitAdapter.adapt(data));
if(physics) {
delegate.scheduleBlockUpdate(x, y, z);
}
access(x, y, z, () -> {
delegate.setBlockData(x, y, z, BukkitAdapter.adapt(data));
if(physics) {
delegate.scheduleBlockUpdate(x, y, z);
}
});
}
@Override
@@ -49,12 +62,12 @@ public class BukkitProtoWorld implements ProtoWorld {
@Override
public BlockState getBlockState(int x, int y, int z) {
return BukkitBlockState.newInstance(delegate.getBlockData(x, y, z));
return access(x, y, z, () -> BukkitBlockState.newInstance(delegate.getBlockData(x, y, z))).orElse(air);
}
@Override
public BlockEntity getBlockEntity(int x, int y, int z) {
return BukkitBlockEntity.newInstance(delegate.getBlockState(x, y, z));
return access(x, y, z, () -> BukkitBlockEntity.newInstance(delegate.getBlockState(x, y, z))).orElse(null);
}
@Override
@@ -64,9 +77,8 @@ public class BukkitProtoWorld implements ProtoWorld {
@Override
public Entity spawnEntity(double x, double y, double z, EntityType entityType) {
return new BukkitEntity(
delegate.spawnEntity(new Location(delegate.getWorld(), x, y, z), ((BukkitEntityType) entityType).getHandle()));
return access((int) x, (int) y, (int) z, () -> new BukkitEntity(
delegate.spawnEntity(new Location(delegate.getWorld(), x, y, z), ((BukkitEntityType) entityType).getHandle()))).orElse(null);
}
@Override
@@ -98,4 +110,23 @@ public class BukkitProtoWorld implements ProtoWorld {
public ServerWorld getWorld() {
return new BukkitServerWorld(delegate.getWorld());
}
private <T> Optional<T> access(int x, int y, int z, Supplier<T> action) {
if(delegate.isInRegion(x, y, z)) {
return Optional.of(action.get());
} else {
LOGGER.warn("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
return Optional.empty();
}
}
private void access(int x, int y, int z, Runnable action) {
if(delegate.isInRegion(x, y, z)) {
action.run();
} else {
LOGGER.warn("Detected world access at coordinates out of bounds: ({}, {}, {}) accessed for region [{}, {}]", x, y, z,
delegate.getCenterChunkX(), delegate.getCenterChunkZ());
}
}
}

View File

@@ -32,7 +32,7 @@ public class BukkitBlockState implements BlockState {
this.delegate = delegate;
}
public static BukkitBlockState newInstance(org.bukkit.block.data.BlockData bukkitData) {
public static BlockState newInstance(org.bukkit.block.data.BlockData bukkitData) {
return new BukkitBlockState(bukkitData);
}