From b7c43797008bcee5f0d7b87a283afab0b9210edb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 2 Dec 2019 19:35:55 +0000 Subject: [PATCH] StartGamePacket: fixed asymmetry in block table handling --- .../network/mcpe/protocol/StartGamePacket.php | 31 +++---------------- .../protocol/types/RuntimeBlockMapping.php | 20 +++++++++--- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index e1e2212c3..64084152c 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -153,7 +153,7 @@ class StartGamePacket extends DataPacket{ /** @var string */ public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort - /** @var array|null ["name" (string), "data" (int16), "legacy_id" (int16)] */ + /** @var ListTag|null */ public $blockTable = null; /** @var array|null string (name) => int16 (legacyID) */ public $itemTable = null; @@ -211,14 +211,8 @@ class StartGamePacket extends DataPacket{ $this->enchantmentSeed = $this->getVarInt(); - $this->blockTable = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $id = $this->getString(); - $data = $this->getSignedLShort(); - $unknown = $this->getSignedLShort(); + $this->blockTable = (new NetworkLittleEndianNBTStream())->read($this->buffer, false, $this->offset, 512); - $this->blockTable[$i] = ["name" => $id, "data" => $data, "legacy_id" => $unknown]; - } $this->itemTable = []; for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ $id = $this->getString(); @@ -286,11 +280,11 @@ class StartGamePacket extends DataPacket{ if($this->blockTable === null){ if(self::$blockTableCache === null){ //this is a really nasty hack, but it'll do for now - self::$blockTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates()); + self::$blockTableCache = (new NetworkLittleEndianNBTStream())->write(RuntimeBlockMapping::generateBlockTable()); } $this->put(self::$blockTableCache); }else{ - $this->put(self::serializeBlockTable($this->blockTable)); + $this->put((new NetworkLittleEndianNBTStream())->write($this->blockTable)); } if($this->itemTable === null){ if(self::$itemTableCache === null){ @@ -304,23 +298,6 @@ class StartGamePacket extends DataPacket{ $this->putString($this->multiplayerCorrelationId); } - private static function serializeBlockTable(array $table) : string{ - $states = new ListTag(); - foreach($table as $v){ - $state = new CompoundTag(); - $state->setTag(new CompoundTag("block", [ - new StringTag("name", $v["name"]), - $v["states"] - ])); - $state->setShort("id", $v["legacy_id"]); - $states->push($state); - } - $stream = new NetworkLittleEndianNBTStream(); - $stream->writeTag($states); - - return $stream->buffer; - } - private static function serializeItemTable(array $table) : string{ $stream = new NetworkBinaryStream(); $stream->putUnsignedVarInt(count($table)); diff --git a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php index ccb92e6e3..0709582c8 100644 --- a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -26,6 +26,8 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\block\BlockIds; use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\tag\StringTag; use pocketmine\utils\BinaryDataException; use function file_get_contents; use function getmypid; @@ -139,11 +141,19 @@ final class RuntimeBlockMapping{ self::$runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; } - /** - * @return array - */ - public static function getBedrockKnownStates() : array{ + public static function generateBlockTable() : ListTag{ self::lazyInit(); - return self::$bedrockKnownStates; + $states = new ListTag(); + //TODO: this assoc array mess really doesn't make sense anymore, we can store NBT directly + foreach(self::$bedrockKnownStates as $v){ + $state = new CompoundTag(); + $state->setTag(new CompoundTag("block", [ + new StringTag("name", $v["name"]), + $v["states"] + ])); + $state->setShort("id", $v["legacy_id"]); + $states->push($state); + } + return $states; } }