Merge branch 'stable' into next-minor

This commit is contained in:
Dylan K. Taylor 2022-07-14 22:04:38 +01:00
commit 93254523e6
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 33 additions and 1 deletions

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe;
use pocketmine\block\tile\Spawnable;
use pocketmine\data\bedrock\EffectIdMap;
use pocketmine\entity\Attribute;
use pocketmine\entity\effect\EffectInstance;
@ -58,6 +59,7 @@ use pocketmine\network\mcpe\handler\PreSpawnPacketHandler;
use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler;
use pocketmine\network\mcpe\handler\SpawnResponsePacketHandler;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
@ -959,6 +961,22 @@ class NetworkSession{
try{
$this->queueCompressed($promise);
$onCompletion();
//TODO: HACK! we send the full tile data here, due to a bug in 1.19.10 which causes items in tiles
//(item frames, lecterns) to not load properly when they are sent in a chunk via the classic chunk
//sending mechanism. We workaround this bug by sending only bare essential data in LevelChunkPacket
//(enough to create the tiles, since BlockActorDataPacket can't create tiles by itself) and then
//send the actual tile properties here.
//TODO: maybe we can stuff these packets inside the cached batch alongside LevelChunkPacket?
$chunk = $currentWorld->getChunk($chunkX, $chunkZ);
if($chunk !== null){
foreach($chunk->getTiles() as $tile){
if(!($tile instanceof Spawnable)){
continue;
}
$this->sendDataPacket(BlockActorDataPacket::create(BlockPosition::fromVector3($tile->getPosition()), $tile->getSerializedSpawnCompound()));
}
}
}finally{
$world->timings->syncChunkSend->stopTiming();
}

View File

@ -24,8 +24,11 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\serializer;
use pocketmine\block\tile\Spawnable;
use pocketmine\block\tile\Tile;
use pocketmine\block\tile\TileFactory;
use pocketmine\data\bedrock\BiomeIds;
use pocketmine\data\bedrock\LegacyBiomeIdToStringIdMap;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
@ -38,6 +41,7 @@ use pocketmine\world\format\PalettedBlockArray;
use pocketmine\world\format\SubChunk;
use function chr;
use function count;
use function get_class;
use function str_repeat;
final class ChunkSerializer{
@ -125,9 +129,19 @@ final class ChunkSerializer{
public static function serializeTiles(Chunk $chunk) : string{
$stream = new BinaryStream();
$nbtSerializer = new NetworkNbtSerializer();
foreach($chunk->getTiles() as $tile){
if($tile instanceof Spawnable){
$stream->put($tile->getSerializedSpawnCompound()->getEncodedNbt());
//TODO: HACK! we send only the bare essentials to create a tile in the chunk itself, due to a bug in
//1.19.10 which causes items in tiles (item frames, lecterns) to not load properly when they are sent in
//a chunk via the classic chunk sending mechanism. We workaround this bug by sendingBlockActorDataPacket
//in NetworkSession to set the actual tile properties after sending the LevelChunkPacket.
$nbt = CompoundTag::create()
->setString(Tile::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($tile)))
->setInt(Tile::TAG_X, $tile->getPosition()->getFloorX())
->setInt(Tile::TAG_Y, $tile->getPosition()->getFloorY())
->setInt(Tile::TAG_Z, $tile->getPosition()->getFloorZ());
$stream->put($nbtSerializer->write(new TreeRoot($nbt)));
}
}