mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 09:56:06 +00:00
Protocol changes for 1.18.0
This commit is contained in:
@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\network\mcpe\serializer;
|
||||
|
||||
use pocketmine\block\tile\Spawnable;
|
||||
use pocketmine\data\bedrock\BiomeIds;
|
||||
use pocketmine\data\bedrock\LegacyBiomeIdToStringMap;
|
||||
use pocketmine\nbt\TreeRoot;
|
||||
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
|
||||
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
||||
@ -32,10 +34,14 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\format\PalettedBlockArray;
|
||||
use pocketmine\world\format\SubChunk;
|
||||
use function chr;
|
||||
use function count;
|
||||
use function str_repeat;
|
||||
|
||||
final class ChunkSerializer{
|
||||
public const LOWER_PADDING_SIZE = 4;
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
@ -58,11 +64,22 @@ final class ChunkSerializer{
|
||||
|
||||
public static function serializeFullChunk(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{
|
||||
$stream = PacketSerializer::encoder($encoderContext);
|
||||
|
||||
//TODO: HACK! fill in fake subchunks to make up for the new negative space client-side
|
||||
for($y = 0; $y < self::LOWER_PADDING_SIZE; $y++){
|
||||
$stream->putByte(8); //subchunk version 8
|
||||
$stream->putByte(0); //0 layers - client will treat this as all-air
|
||||
}
|
||||
|
||||
$subChunkCount = self::getSubChunkCount($chunk);
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX, $writtenCount = 0; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){
|
||||
self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream, false);
|
||||
}
|
||||
$stream->put($chunk->getBiomeIdArray());
|
||||
|
||||
//TODO: right now we don't support 3D natively, so we just 3Dify our 2D biomes so they fill the column
|
||||
$encodedBiomePalette = self::serializeBiomesAsPalette($chunk);
|
||||
$stream->put(str_repeat($encodedBiomePalette, 25));
|
||||
|
||||
$stream->putByte(0); //border block array count
|
||||
//Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client.
|
||||
|
||||
@ -116,4 +133,39 @@ final class ChunkSerializer{
|
||||
|
||||
return $stream->getBuffer();
|
||||
}
|
||||
|
||||
private static function serializeBiomesAsPalette(Chunk $chunk) : string{
|
||||
$biomeIdMap = LegacyBiomeIdToStringMap::getInstance();
|
||||
$biomePalette = new PalettedBlockArray($chunk->getBiomeId(0, 0));
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
$biomeId = $chunk->getBiomeId($x, $z);
|
||||
if($biomeIdMap->legacyToString($biomeId) === null){
|
||||
//make sure we aren't sending bogus biomes - the 1.18.0 client crashes if we do this
|
||||
$biomeId = BiomeIds::OCEAN;
|
||||
}
|
||||
for($y = 0; $y < 16; ++$y){
|
||||
$biomePalette->set($x, $y, $z, $biomeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$biomePaletteBitsPerBlock = $biomePalette->getBitsPerBlock();
|
||||
$encodedBiomePalette =
|
||||
chr(($biomePaletteBitsPerBlock << 1) | 1) . //the last bit is non-persistence (like for blocks), though it has no effect on biomes since they always use integer IDs
|
||||
$biomePalette->getWordArray();
|
||||
|
||||
//these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here
|
||||
//but since we know they are always unsigned, we can avoid the extra fcall overhead of
|
||||
//zigzag and just shift directly.
|
||||
$biomePaletteArray = $biomePalette->getPalette();
|
||||
if($biomePaletteBitsPerBlock !== 0){
|
||||
$encodedBiomePalette .= Binary::writeUnsignedVarInt(count($biomePaletteArray) << 1);
|
||||
}
|
||||
foreach($biomePaletteArray as $p){
|
||||
$encodedBiomePalette .= Binary::writeUnsignedVarInt($p << 1);
|
||||
}
|
||||
|
||||
return $encodedBiomePalette;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user