mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
warn at out-of-bounds access rather than crash on Bukkit.
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user