mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 09:56:06 +00:00
extract a BiomeArray unit from Chunk
this now also properly validates data read from disk.
This commit is contained in:
@ -25,6 +25,7 @@ namespace pocketmine\world\format\io;
|
||||
|
||||
use pocketmine\block\BlockLegacyIds;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\world\format\BiomeArray;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\format\LightArray;
|
||||
use pocketmine\world\format\PalettedBlockArray;
|
||||
@ -111,7 +112,7 @@ final class FastChunkSerializer{
|
||||
$terrainGenerated = (bool) ($flags & 1);
|
||||
|
||||
$subChunks = [];
|
||||
$biomeIds = "";
|
||||
$biomeIds = null;
|
||||
$heightMap = [];
|
||||
if($terrainGenerated){
|
||||
$count = $stream->getByte();
|
||||
@ -132,7 +133,7 @@ final class FastChunkSerializer{
|
||||
);
|
||||
}
|
||||
|
||||
$biomeIds = $stream->get(256);
|
||||
$biomeIds = new BiomeArray($stream->get(256));
|
||||
if($lightPopulated){
|
||||
$heightMap = array_values(unpack("S*", $stream->get(512)));
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\BinaryDataException;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\world\format\BiomeArray;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\format\io\BaseWorldProvider;
|
||||
use pocketmine\world\format\io\ChunkUtils;
|
||||
@ -232,8 +233,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
/** @var SubChunk[] $subChunks */
|
||||
$subChunks = [];
|
||||
|
||||
/** @var string $biomeIds */
|
||||
$biomeIds = "";
|
||||
/** @var BiomeArray|null $biomeArray */
|
||||
$biomeArray = null;
|
||||
|
||||
$chunkVersion = ord($this->db->get($index . self::TAG_VERSION));
|
||||
$hasBeenUpgraded = $chunkVersion < self::CURRENT_LEVEL_CHUNK_VERSION;
|
||||
@ -326,7 +327,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
|
||||
try{
|
||||
$binaryStream->get(512); //heightmap, discard it
|
||||
$biomeIds = $binaryStream->get(256);
|
||||
$biomeArray = new BiomeArray($binaryStream->get(256)); //never throws
|
||||
}catch(BinaryDataException $e){
|
||||
throw new CorruptedChunkException($e->getMessage(), 0, $e);
|
||||
}
|
||||
@ -360,7 +361,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
|
||||
try{
|
||||
$binaryStream->get(256); //heightmap, discard it
|
||||
$biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024))));
|
||||
$biomeArray = new BiomeArray(ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024))))); //never throws
|
||||
}catch(BinaryDataException $e){
|
||||
throw new CorruptedChunkException($e->getMessage(), 0, $e);
|
||||
}
|
||||
@ -398,7 +399,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
$subChunks,
|
||||
$entities,
|
||||
$tiles,
|
||||
$biomeIds
|
||||
$biomeArray
|
||||
);
|
||||
|
||||
//TODO: tile ticks, biome states (?)
|
||||
|
@ -25,9 +25,11 @@ namespace pocketmine\world\format\io\region;
|
||||
|
||||
use pocketmine\nbt\BigEndianNbtSerializer;
|
||||
use pocketmine\nbt\NbtDataException;
|
||||
use pocketmine\nbt\tag\ByteArrayTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntArrayTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\world\format\BiomeArray;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\format\io\ChunkUtils;
|
||||
use pocketmine\world\format\io\exception\CorruptedChunkException;
|
||||
@ -72,10 +74,18 @@ trait LegacyAnvilChunkTrait{
|
||||
}
|
||||
}
|
||||
|
||||
$makeBiomeArray = function(string $biomeIds) : BiomeArray{
|
||||
try{
|
||||
return new BiomeArray($biomeIds);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
throw new CorruptedChunkException($e->getMessage(), 0, $e);
|
||||
}
|
||||
};
|
||||
$biomeArray = null;
|
||||
if($chunk->hasTag("BiomeColors", IntArrayTag::class)){
|
||||
$biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format
|
||||
}else{
|
||||
$biomeIds = $chunk->getByteArray("Biomes", "");
|
||||
$biomeArray = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format
|
||||
}elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){
|
||||
$biomeArray = $makeBiomeArray($chunk->getByteArray("Biomes"));
|
||||
}
|
||||
|
||||
$result = new Chunk(
|
||||
@ -84,7 +94,7 @@ trait LegacyAnvilChunkTrait{
|
||||
$subChunks,
|
||||
$chunk->hasTag("Entities", ListTag::class) ? self::getCompoundList("Entities", $chunk->getListTag("Entities")) : [],
|
||||
$chunk->hasTag("TileEntities", ListTag::class) ? self::getCompoundList("TileEntities", $chunk->getListTag("TileEntities")) : [],
|
||||
$biomeIds
|
||||
$biomeArray
|
||||
);
|
||||
$result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0);
|
||||
$result->setGenerated();
|
||||
|
@ -29,6 +29,7 @@ use pocketmine\nbt\NbtDataException;
|
||||
use pocketmine\nbt\tag\ByteArrayTag;
|
||||
use pocketmine\nbt\tag\IntArrayTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\world\format\BiomeArray;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\format\io\ChunkUtils;
|
||||
use pocketmine\world\format\io\exception\CorruptedChunkException;
|
||||
@ -69,12 +70,18 @@ class McRegion extends RegionWorldProvider{
|
||||
$subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]);
|
||||
}
|
||||
|
||||
$makeBiomeArray = function(string $biomeIds) : BiomeArray{
|
||||
try{
|
||||
return new BiomeArray($biomeIds);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
throw new CorruptedChunkException($e->getMessage(), 0, $e);
|
||||
}
|
||||
};
|
||||
$biomeIds = null;
|
||||
if($chunk->hasTag("BiomeColors", IntArrayTag::class)){
|
||||
$biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format
|
||||
$biomeIds = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format
|
||||
}elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){
|
||||
$biomeIds = $chunk->getByteArray("Biomes");
|
||||
}else{
|
||||
$biomeIds = "";
|
||||
$biomeIds = $makeBiomeArray($chunk->getByteArray("Biomes"));
|
||||
}
|
||||
|
||||
$result = new Chunk(
|
||||
|
Reference in New Issue
Block a user