Merge branch 'stable'

This commit is contained in:
Dylan K. Taylor
2019-07-13 18:08:45 +01:00
57 changed files with 1530 additions and 574 deletions

View File

@ -28,7 +28,6 @@ use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\utils\BinaryStream;
use pocketmine\world\format\Chunk;
use function count;
use function pack;
final class ChunkSerializer{
@ -46,8 +45,6 @@ final class ChunkSerializer{
public static function serialize(Chunk $chunk, ?string $tiles = null) : string{
$stream = new NetworkBinaryStream();
$subChunkCount = $chunk->getSubChunkSendCount();
$stream->putByte($subChunkCount);
for($y = 0; $y < $subChunkCount; ++$y){
$layers = $chunk->getSubChunk($y)->getBlockLayers();
$stream->putByte(8); //version
@ -64,7 +61,6 @@ final class ChunkSerializer{
}
}
}
$stream->put(pack("v*", ...$chunk->getHeightMapArray()));
$stream->put($chunk->getBiomeIdArray());
$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.

View File

@ -26,12 +26,14 @@ namespace pocketmine\network\mcpe\serializer;
#include <rules/DataPacket.h>
use pocketmine\entity\Attribute;
use pocketmine\item\Durable;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\ItemIds;
use pocketmine\math\Vector3;
use pocketmine\nbt\NbtDataException;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\BadPacketException;
use pocketmine\network\mcpe\protocol\types\CommandOriginData;
@ -45,6 +47,9 @@ use function strlen;
class NetworkBinaryStream extends BinaryStream{
private const DAMAGE_TAG = "Damage"; //TAG_Int
private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___";
/**
* @return string
* @throws BinaryDataException
@ -93,12 +98,10 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = $this->getVarInt();
$data = $auxValue >> 8;
if($data === 0x7fff){
$data = -1;
}
$cnt = $auxValue & 0xff;
$nbtLen = $this->getLShort();
/** @var CompoundTag|null $compound */
$compound = null;
if($nbtLen === 0xffff){
@ -129,6 +132,21 @@ class NetworkBinaryStream extends BinaryStream{
$this->getVarLong(); //"blocking tick" (ffs mojang)
}
if($compound !== null){
if($compound->hasTag(self::DAMAGE_TAG, IntTag::class)){
$data = $compound->getInt(self::DAMAGE_TAG);
$compound->removeTag(self::DAMAGE_TAG);
if($compound->count() === 0){
$compound = null;
goto end;
}
}
if(($conflicted = $compound->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){
$compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
$compound->setTag(self::DAMAGE_TAG, $conflicted);
}
}
end:
try{
return ItemFactory::get($id, $data, $cnt, $compound);
}catch(\InvalidArgumentException $e){
@ -148,10 +166,26 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = (($item->getMeta() & 0x7fff) << 8) | $item->getCount();
$this->putVarInt($auxValue);
$nbt = null;
if($item->hasNamedTag()){
$nbt = clone $item->getNamedTag();
}
if($item instanceof Durable and $item->getDamage() > 0){
if($nbt !== null){
if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){
$nbt->removeTag(self::DAMAGE_TAG);
$nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing);
}
}else{
$nbt = new CompoundTag();
}
$nbt->setInt(self::DAMAGE_TAG, $item->getDamage());
}
if($nbt !== null){
$this->putLShort(0xffff);
$this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0
$this->put((new NetworkNbtSerializer())->write(new TreeRoot($item->getNamedTag())));
$this->put((new NetworkNbtSerializer())->write(new TreeRoot($nbt)));
}else{
$this->putLShort(0);
}
@ -164,6 +198,29 @@ class NetworkBinaryStream extends BinaryStream{
}
}
public function getRecipeIngredient() : Item{
$id = $this->getVarInt();
if($id === 0){
return ItemFactory::get(ItemIds::AIR, 0, 0);
}
$meta = $this->getVarInt();
if($meta === 0x7fff){
$meta = -1;
}
$count = $this->getVarInt();
return ItemFactory::get($id, $meta, $count);
}
public function putRecipeIngredient(Item $item) : void{
if($item->isNull()){
$this->putVarInt(0);
}else{
$this->putVarInt($item->getId());
$this->putVarInt($item->getMeta() & 0x7fff);
$this->putVarInt($item->getCount());
}
}
/**
* Decodes entity metadata from the stream.
*