From fd9d08fd1709c9651fcb9be46eac9a42eafe6fc1 Mon Sep 17 00:00:00 2001 From: "haniokasai@Desktop" Date: Thu, 31 Oct 2019 12:50:14 +0900 Subject: [PATCH] =?UTF-8?q?1.13=E5=AF=BE=E5=BF=9C=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/php/php.ini-development | 2 +- bin/php/php.ini-production | 2 +- src/pocketmine/MemoryManager.php | 8 +- src/pocketmine/Player.php | 58 +++- src/pocketmine/PocketMine.php | 30 +- src/pocketmine/Server.php | 15 +- src/pocketmine/entity/Human.php | 74 +++- src/pocketmine/entity/Skin.php | 126 +++++-- src/pocketmine/inventory/CraftingManager.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/level/Explosion.php | 7 - .../network/mcpe/NetworkBinaryStream.php | 67 +++- .../network/mcpe/NetworkSession.php | 5 - .../mcpe/PlayerNetworkSessionAdapter.php | 10 +- .../AvailableActorIdentifiersPacket.php | 12 +- .../protocol/BiomeDefinitionListPacket.php | 12 +- .../network/mcpe/protocol/PacketPool.php | 1 - .../mcpe/protocol/PlayerListPacket.php | 36 +- .../mcpe/protocol/PlayerSkinPacket.php | 30 +- .../network/mcpe/protocol/ProtocolInfo.php | 317 +++++++++--------- .../protocol/ResourcePackDataInfoPacket.php | 2 +- .../network/mcpe/protocol/RespawnPacket.php | 12 + .../network/mcpe/protocol/StartGamePacket.php | 32 +- .../mcpe/protocol/types/PlayerListEntry.php | 10 +- .../mcpe/protocol/types/ResourcePackType.php | 14 +- .../protocol/types/RuntimeBlockMapping.php | 40 ++- src/pocketmine/plugin/PluginManager.php | 8 - src/pocketmine/scheduler/AsyncWorker.php | 4 +- src/pocketmine/scheduler/SendUsageTask.php | 163 +++++++++ src/pocketmine/utils/Internet.php | 142 ++++++++ src/pocketmine/utils/InternetException.php | 28 ++ src/pocketmine/utils/Timezone.php | 8 +- src/pocketmine/utils/Utils.php | 35 +- 33 files changed, 922 insertions(+), 392 deletions(-) create mode 100644 src/pocketmine/scheduler/SendUsageTask.php create mode 100644 src/pocketmine/utils/Internet.php create mode 100644 src/pocketmine/utils/InternetException.php diff --git a/bin/php/php.ini-development b/bin/php/php.ini-development index 6fd401821..3ea226d31 100644 --- a/bin/php/php.ini-development +++ b/bin/php/php.ini-development @@ -1502,7 +1502,7 @@ session.trans_sid_tags = "a=href,area=href,frame=src,form=" ; URL rewriter does not rewrite absolute URLs by default. ; To enable rewrites for absolute pathes, target hosts must be specified -; at RUNTIME. i.e. use ini_set() +; at RUNTIME. i.e. use //ini_set() ;
tags is special. PHP will check action attribute's URL regardless ; of session.trans_sid_tags setting. ; If no host is defined, HTTP_HOST will be used for allowed host. diff --git a/bin/php/php.ini-production b/bin/php/php.ini-production index 91c6129d4..7c8c34385 100644 --- a/bin/php/php.ini-production +++ b/bin/php/php.ini-production @@ -1509,7 +1509,7 @@ session.trans_sid_tags = "a=href,area=href,frame=src,form=" ; URL rewriter does not rewrite absolute URLs by default. ; To enable rewrites for absolute pathes, target hosts must be specified -; at RUNTIME. i.e. use ini_set() +; at RUNTIME. i.e. use //ini_set() ; tags is special. PHP will check action attribute's URL regardless ; of session.trans_sid_tags setting. ; If no host is defined, HTTP_HOST will be used for allowed host. diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index d6e03a393..218725fa2 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -145,9 +145,9 @@ private function init(){ $hardLimit = ((int) $this->server->getProperty("memory.main-hard-limit", $defaultMemory)); if($hardLimit <= 0){ - ini_set("memory_limit", '-1'); + //ini_set("memory_limit", '-1'); }else{ - ini_set("memory_limit", $hardLimit . "M"); + //ini_set("memory_limit", $hardLimit . "M"); } $this->globalMemoryLimit = ((int) $this->server->getProperty("memory.global-limit", 0)) * 1024 * 1024; @@ -323,7 +323,7 @@ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $max */ public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger){ $hardLimit = ini_get('memory_limit'); - ini_set('memory_limit', '-1'); + //ini_set('memory_limit', '-1'); gc_disable(); if(!file_exists($outputFolder)){ @@ -466,7 +466,7 @@ public static function dumpMemory($startingObject, string $outputFolder, int $ma $logger->info("[Dump] Finished!"); - ini_set('memory_limit', $hardLimit); + //ini_set('memory_limit', $hardLimit); gc_enable(); } diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5b1d79ee8..562486867 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -160,6 +160,8 @@ use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; +use pocketmine\utils\SerializedImage; +use pocketmine\utils\SkinAnimation; use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; use function abs; @@ -1127,6 +1129,7 @@ public function doFirstSpawn(){ protected function sendRespawnPacket(Vector3 $pos){ $pk = new RespawnPacket(); $pk->position = $pos->add(0, $this->baseOffset, 0); + $pk->respawnState = RespawnPacket::STATE_SEARCHING_FOR_SPAWN; $this->dataPacket($pk); } @@ -1940,12 +1943,47 @@ public function handleLogin(LoginPacket $packet) : bool{ $this->uuid = UUID::fromString($packet->clientUUID); $this->rawUUID = $this->uuid->toBinary(); + if(isset($packet->clientData["SkinData"])){ + $data = base64_decode($packet->clientData["SkinData"]); + if(isset($packet->clientData["SkinImageWidth"], $packet->clientData["SkinImageHeight"])){ + $skinData = new SerializedImage((int) $packet->clientData['SkinImageWidth'], (int) $packet->clientData['SkinImageHeight'], $data); + }else{ + $skinData = SerializedImage::fromLegacy(base64_decode($data)); + } + } else { + $skinData = SerializedImage::null(); + } + + if(isset($packet->clientData["CapeData"])){ + $data = base64_decode($packet->clientData["CapeData"]); + if(isset($packet->clientData["CapeImageWidth"], $packet->clientData["CapeImageHeight"])){ + $capeData = new SerializedImage((int) $packet->clientData["CapeImageWidth"], (int) $packet->clientData["CapeImageHeight"], $data); + }else{ + $capeData = SerializedImage::fromLegacy(base64_decode($data)); + } + } else { + $capeData = SerializedImage::null(); + } + + $animations = []; + if(isset($packet->clientData["AnimatedImageData"])){ + foreach($packet->clientData["AnimatedImageData"] as $data){ + $animations[] = new SkinAnimation(new SerializedImage($data["ImageWidth"], $data["ImageHeight"], base64_decode($data["Image"])), $data["Type"], $data["Frames"]); + } + } + $skin = new Skin( $packet->clientData["SkinId"], - base64_decode($packet->clientData["SkinData"] ?? ""), - base64_decode($packet->clientData["CapeData"] ?? ""), - $packet->clientData["SkinGeometryName"] ?? "", - base64_decode($packet->clientData["SkinGeometry"] ?? "") + base64_decode($packet->clientData["SkinResourcePatch"] ?? ""), + $skinData, + $animations, + $capeData, + base64_decode($packet->clientData["SkinGeometryData"] ?? ""), + base64_decode($packet->clientData["AnimationData"] ?? ""), + (bool) ($packet->clientData["PremiumSkin"] ?? false), + (bool) ($packet->clientData["PersonaSkin"] ?? false), + (bool) ($packet->clientData["CapeOnClassicSkin"] ?? false), + $packet->clientData["CapeId"] ?? "" ); if(!$skin->isValid()){ @@ -1984,6 +2022,18 @@ public function handleLogin(LoginPacket $packet) : bool{ return true; } + public function handleRespawn(RespawnPacket $packet): bool + { + if (!$this->isAlive() && $packet->respawnState === RespawnPacket::STATE_CLIENT_READY_TO_SPAWN) { + $packet = new RespawnPacket(); + $packet->position = $this->asVector3(); + $packet->respawnState = RespawnPacket::STATE_READY_TO_SPAWN; + $this->dataPacket($packet); + } + + return true; + } + public function sendPlayStatus(int $status, bool $immediate = false){ $pk = new PlayStatusPacket(); $pk->status = $status; diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 90292b77d..52c460420 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -169,12 +169,12 @@ function server(){ set_time_limit(0); //Who set it to 30 seconds?!?! - ini_set("allow_url_fopen", '1'); - ini_set("display_errors", '1'); - ini_set("display_startup_errors", '1'); - ini_set("default_charset", "utf-8"); + //ini_set("allow_url_fopen", '1'); + //ini_set("display_errors", '1'); + //ini_set("display_startup_errors", '1'); + //ini_set("default_charset", "utf-8"); - ini_set("memory_limit", '-1'); + //ini_set("memory_limit", '-1'); define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'src' . DIRECTORY_SEPARATOR . 'pocketmine' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR); @@ -236,28 +236,10 @@ function server(){ $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); define('pocketmine\VERSION', $version->getFullVersion(true)); - $gitHash = str_repeat("00", 20); - - if(\Phar::running(true) === ""){ - if(Utils::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ - $gitHash = trim($out); - if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified - $gitHash .= "-dirty"; - } - } - }else{ - $phar = new \Phar(\Phar::running(false)); - $meta = $phar->getMetadata(); - if(isset($meta["git"])){ - $gitHash = $meta["git"]; - } - } - - define('pocketmine\GIT_COMMIT', $gitHash); @define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1); - @ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors + //@//ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors $exitCode = 0; do{ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index fbd025240..48a47d46b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1555,21 +1555,12 @@ public function __construct(\ClassLoader $autoloader, \AttachableThreadedLogger $this->baseLang = new BaseLang($this->getConfigString("language", $this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE))); $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); - if(\pocketmine\IS_DEVELOPMENT_BUILD and !((bool) $this->getProperty("settings.enable-dev-builds", false))){ - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error2")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error3")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error5", ["https://github.com/pmmp/PocketMine-MP/releases"])); - $this->forceShutdown(); - return; - } if(((int) ini_get('zend.assertions')) !== -1){ $this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini."); } - ini_set('assert.exception', '1'); + //ini_set('assert.exception', '1'); if($this->logger instanceof MainLogger){ $this->logger->setLogDebug(\pocketmine\DEBUG > 1); @@ -2265,8 +2256,8 @@ public function crashDump(){ } $this->hasStopped = false; - ini_set("error_reporting", '0'); - ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems + //ini_set("error_reporting", '0'); + //ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems try{ $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create")); $dump = new CrashDump($this); diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 0a9def938..1f8eca587 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -42,7 +42,9 @@ use pocketmine\level\Level; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; @@ -54,8 +56,11 @@ use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\Player; +use pocketmine\utils\SerializedImage; +use pocketmine\utils\SkinAnimation; use pocketmine\utils\UUID; use function array_filter; +use function array_map; use function array_merge; use function array_rand; use function array_values; @@ -115,13 +120,35 @@ public function __construct(Level $level, CompoundTag $nbt){ * @throws \InvalidArgumentException */ protected static function deserializeSkinNBT(CompoundTag $skinTag) : Skin{ - $skin = new Skin( - $skinTag->getString("Name"), - $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) - $skinTag->getByteArray("CapeData", ""), - $skinTag->getString("GeometryName", ""), - $skinTag->getByteArray("GeometryData", "") - ); + if($skinTag->hasTag("SkinData")) { //new format (1.13+) + $skin = new Skin( + $skinTag->getString("SkinId"), + $skinTag->getByteArray("SkinResourcePatch"), + new SerializedImage($skinTag->getInt("SkinImageWidth"), $skinTag->getInt("SkinImageHeight"), $skinTag->getByteArray("SkinData")), + array_map(static function(CompoundTag $animation) : SkinAnimation { + return new SkinAnimation(new SerializedImage($animation->getInt("ImageWidth"), $animation->getInt("ImageHeight"), $animation->getByteArray("Image")), $animation->getInt("Type"), $animation->getFloat("Frames")); + }, $skinTag->getListTag("AnimationImageData")->getAllValues()), + new SerializedImage($skinTag->getInt("CapeImageWidth"), $skinTag->getInt("CapeImageHeight"), $skinTag->getByteArray("CapeData")), + $skinTag->getByteArray("GeometryData"), + $skinTag->getByteArray("AnimationData"), + $skinTag->getByte("PremiumSkin") === 1, + $skinTag->getByte("PersonaSkin") === 1, + $skinTag->getByte("CapeOnClassicSkin") === 1, + $skinTag->getString("CapeId") + ); + } else { //old format + $skin = new Skin( + $skinTag->getString("Name"), + "", + SerializedImage::fromLegacy($skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data")), //old data (this used to be saved as a StringTag in older versions of PM) + [], + SerializedImage::fromLegacy($skinTag->getByteArray("CapeData", "")), + $skinTag->getByteArray("GeometryData", ""), + "", + Skin::convertLegacyGeometryName($skinTag->getString("GeometryName", "")) + ); + } + $skin->validate(); return $skin; } @@ -606,7 +633,7 @@ protected function initHumanData() : void{ $this->setNameTag($this->namedtag->getString("NameTag")); } - $this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag()); + $this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData()->getData(), $this->getNameTag()); } protected function initEntity() : void{ @@ -828,11 +855,32 @@ public function saveNBT() : void{ if($this->skin !== null){ $this->namedtag->setTag(new CompoundTag("Skin", [ - new StringTag("Name", $this->skin->getSkinId()), - new ByteArrayTag("Data", $this->skin->getSkinData()), - new ByteArrayTag("CapeData", $this->skin->getCapeData()), - new StringTag("GeometryName", $this->skin->getGeometryName()), - new ByteArrayTag("GeometryData", $this->skin->getGeometryData()) + new StringTag("SkinId", $this->skin->getSkinId()), + new ByteArrayTag("SkinData", $this->skin->getSkinData()->getData()), + new IntTag("SkinImageWidth", $this->skin->getSkinData()->getWidth()), + new IntTag("SkinImageHeight", $this->skin->getSkinData()->getHeight()), + + new StringTag("CapeId", $this->skin->getSkinId()), + new ByteArrayTag("CapeData", $this->skin->getCapeData()->getData()), + new IntTag("CapeImageWidth", $this->skin->getCapeData()->getWidth()), + new IntTag("CapeImageHeight", $this->skin->getCapeData()->getHeight()), + + new ByteArrayTag("SkinResourcePatch", $this->skin->getSkinResourcePatch()), + new ByteArrayTag("GeometryData", $this->skin->getGeometryData()), + new ByteArrayTag("AnimationData", $this->skin->getAnimationData()), + new ByteTag("PremiumSkin", $this->skin->isPremium() ? 1 : 0), + new ByteTag("PersonaSkin", $this->skin->isPersona() ? 1 : 0), + new ByteTag("CapeOnClassicSkin", $this->skin->isCapeOnClassic() ? 1 : 0), + + new ListTag("AnimationImageData", array_map(static function(SkinAnimation $animation) : CompoundTag { + return new CompoundTag("", [ + new FloatTag("Frames", $animation->getFrames()), + new IntTag("Type", $animation->getType()), + new IntTag("ImageWidth", $animation->getImage()->getWidth()), + new IntTag("ImageHeight", $animation->getImage()->getHeight()), + new ByteArrayTag("Image", $animation->getImage()->getData()), + ]); + }, $this->skin->getAnimations())) ])); } } diff --git a/src/pocketmine/entity/Skin.php b/src/pocketmine/entity/Skin.php index d5a1477ea..8b96637cf 100644 --- a/src/pocketmine/entity/Skin.php +++ b/src/pocketmine/entity/Skin.php @@ -24,10 +24,10 @@ namespace pocketmine\entity; use Ahc\Json\Comment as CommentedJsonDecoder; -use function implode; -use function in_array; +use InvalidArgumentException; +use pocketmine\utils\SerializedImage; +use pocketmine\utils\SkinAnimation; use function json_encode; -use function strlen; class Skin{ public const ACCEPTED_SKIN_SIZES = [ @@ -39,48 +39,112 @@ class Skin{ /** @var string */ private $skinId; /** @var string */ + private $skinResourcePatch; + /** @var SerializedImage */ private $skinData; - /** @var string */ + /** @var SkinAnimation[] */ + private $animations; + /** @var SerializedImage */ private $capeData; /** @var string */ - private $geometryName; - /** @var string */ private $geometryData; + /** @var string */ + private $animationData; + /** @var bool */ + private $premium; + /** @var bool */ + private $persona; + /** @var bool */ + private $capeOnClassic; + /** @var ?string */ + private $capeId; - public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){ + public function __construct(string $skinId, string $skinResourcePatch, SerializedImage $skinData, array $animations = [], SerializedImage $capeData = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, $capeOnClassic = false, string $capeId = null){ $this->skinId = $skinId; + $this->skinResourcePatch = $skinResourcePatch; $this->skinData = $skinData; + $this->animations = $animations; $this->capeData = $capeData; - $this->geometryName = $geometryName; $this->geometryData = $geometryData; + $this->animationData = $animationData; + $this->premium = $premium; + $this->persona = $persona; + $this->capeOnClassic = $capeOnClassic; + $this->capeId = $capeId; + + $this->debloatGeometryData(); + } + + public static function convertLegacyGeometryName(string $geometryName) : string{ + return '{"geometry" : {"default" : "' . $geometryName . '"}}'; + } + + /** + * @return string + */ + public function getSkinResourcePatch() : string{ + return $this->skinResourcePatch; + } + + /** + * @return SkinAnimation[] + */ + public function getAnimations() : array{ + return $this->animations; + } + + /** + * @return string + */ + public function getAnimationData() : string{ + return $this->animationData; + } + + /** + * @return bool + */ + public function isPremium() : bool{ + return $this->premium; + } + + /** + * @return bool + */ + public function isPersona() : bool{ + return $this->persona; + } + + /** + * @return bool + */ + public function isCapeOnClassic() : bool{ + return $this->capeOnClassic; + } + + public function getCapeId() : string{ + return $this->capeId ?? ""; } /** - * @deprecated * @return bool + * @deprecated */ public function isValid() : bool{ try{ $this->validate(); + return true; - }catch(\InvalidArgumentException $e){ + }catch(InvalidArgumentException $e){ return false; } } /** - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function validate() : void{ if($this->skinId === ""){ - throw new \InvalidArgumentException("Skin ID must not be empty"); - } - $len = strlen($this->skinData); - if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){ - throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")"); - } - if($this->capeData !== "" and strlen($this->capeData) !== 8192){ - throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)"); + throw new InvalidArgumentException("Skin ID must not be empty"); } //TODO: validate geometry } @@ -93,24 +157,21 @@ public function getSkinId() : string{ } /** - * @return string + * @return SerializedImage */ - public function getSkinData() : string{ + public function getSkinData() : SerializedImage{ return $this->skinData; } /** - * @return string + * @return SerializedImage */ - public function getCapeData() : string{ - return $this->capeData; - } + public function getCapeData() : SerializedImage{ + if($this->capeData === null){ + return new SerializedImage(0, 0, ''); + } - /** - * @return string - */ - public function getGeometryName() : string{ - return $this->geometryName; + return $this->capeData; } /** @@ -132,4 +193,9 @@ public function debloatGeometryData() : void{ $this->geometryData = (string) json_encode((new CommentedJsonDecoder())->decode($this->geometryData)); } } + + public function getFullSkinId() : string{ + return $this->skinId . "_" . $this->getCapeId(); + } + } diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 528b364a9..0cfa15318 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -51,7 +51,7 @@ public function __construct(){ } public function init() : void{ - $recipes = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "recipes.json"), true); + $recipes = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "recipes.json"), true)["recipes"]; $itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']); foreach($recipes as $recipe){ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 664e07bba..2e0b02074 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -126,7 +126,7 @@ public static function fromString(string $str, bool $multiple = false){ public static function initCreativeItems(){ self::clearCreativeItems(); - $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "creativeitems.json"), true); + $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "creativeitems.json"), true)["items"]; foreach($creativeItems as $data){ $item = Item::jsonDeserialize($data); diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index e234fdd3e..d3906790e 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -38,7 +38,6 @@ use pocketmine\level\utils\SubChunkIteratorManager; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\tile\Chest; use pocketmine\tile\Container; @@ -260,12 +259,6 @@ public function explodeB() : bool{ $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z); } - $pk = new ExplodePacket(); - $pk->position = $this->source->asVector3(); - $pk->radius = $this->size; - $pk->records = $send; - $this->level->broadcastPacketToViewers($source, $pk); - $this->level->addParticle(new HugeExplodeSeedParticle($source)); $this->level->broadcastLevelSoundEvent($source, LevelSoundEventPacket::SOUND_EXPLODE); diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index ba48a129b..d42b34909 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -27,6 +27,7 @@ use pocketmine\entity\Attribute; use pocketmine\entity\Entity; +use pocketmine\entity\Skin; use pocketmine\item\Durable; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -39,6 +40,8 @@ use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryStream; +use pocketmine\utils\SerializedImage; +use pocketmine\utils\SkinAnimation; use pocketmine\utils\UUID; use function count; use function strlen; @@ -74,6 +77,65 @@ public function putUUID(UUID $uuid) : void{ $this->putLInt($uuid->getPart(2)); } + public function putSkin(Skin $skin) : void{ + $this->putString($skin->getSkinId()); + $this->putString($skin->getSkinResourcePatch()); + $this->putImage($skin->getSkinData()); + + $this->putLInt(count($animations = $skin->getAnimations())); + foreach($animations as $animation){ + $this->putImage($animation->getImage()); + $this->putLInt($animation->getType()); + $this->putLFloat($animation->getFrames()); + } + + $this->putImage($skin->getCapeData()); + $this->putString($skin->getGeometryData()); + $this->putString($skin->getAnimationData()); + $this->putBool($skin->isPremium()); + $this->putBool($skin->isPersona()); + $this->putBool($skin->isCapeOnClassic()); + $this->putString($skin->getCapeId()); + $this->putString($skin->getFullSkinId()); + } + + public function getSkin() : Skin{ + $skinId = $this->getString(); + $skinResourcePatch = $this->getString(); + $skinData = $this->getImage(); + + $animations = []; + for($i = 0, $count = $this->getLInt(); $i < $count; ++$i){ + $animations[] = new SkinAnimation($this->getImage(), $this->getLInt(), $this->getLFloat()); + } + + $capeData = $this->getImage(); + $geometryData = $this->getString(); + $animationData = $this->getString(); + $premium = $this->getBool(); + $persona = $this->getBool(); + $capeOnClassic = $this->getBool(); + $capeId = $this->getString(); + $fullSkinId = $this->getString(); + + return new Skin($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId); + } + + + public function putImage(SerializedImage $image) : void{ + $this->putLInt($image->getWidth()); + $this->putLInt($image->getHeight()); + $this->putString($image->getData()); + } + + public function getImage() : SerializedImage{ + $width = $this->getLInt(); + $height = $this->getLInt(); + $data = $this->getString(); + + return new SerializedImage($width, $height, $data); + } + public function getSlot() : Item{ $id = $this->getVarInt(); if($id === 0){ @@ -127,6 +189,7 @@ public function getSlot() : Item{ } } end: + return ItemFactory::get($id, $data, $cnt, $nbt); } @@ -185,6 +248,7 @@ public function getRecipeIngredient() : Item{ $meta = -1; } $count = $this->getVarInt(); + return ItemFactory::get($id, $meta, $count); } @@ -457,9 +521,10 @@ public function getVector3() : Vector3{ * Note: ONLY use this where it is reasonable to allow not specifying the vector. * For all other purposes, use the non-nullable version. * + * @param Vector3|null $vector + * * @see NetworkBinaryStream::putVector3() * - * @param Vector3|null $vector */ public function putVector3Nullable(?Vector3 $vector) : void{ if($vector){ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 4de360f3a..4b0df060c 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -62,7 +62,6 @@ use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\EventPacket; -use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket; use pocketmine\network\mcpe\protocol\HurtArmorPacket; @@ -247,10 +246,6 @@ public function handleAddPainting(AddPaintingPacket $packet) : bool{ return false; } - public function handleExplode(ExplodePacket $packet) : bool{ - return false; - } - public function handleLevelSoundEventPacketV1(LevelSoundEventPacketV1 $packet) : bool{ return false; } diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index 7e546647c..c89ad8116 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -59,6 +59,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; +use pocketmine\network\mcpe\protocol\RespawnPacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; @@ -193,7 +194,12 @@ public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ return true; //this is a broken useless packet, so we don't use it } - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ + public function handleRespawn(RespawnPacket $packet): bool + { + return $this->player->handleRespawn($packet); + } + + public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ return $this->player->handleAdventureSettings($packet); } @@ -248,7 +254,7 @@ public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $p } public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); + return $this->player->changeSkin($packet->skin); } public function handleBookEdit(BookEditPacket $packet) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index c70ece1b0..48e06c779 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -27,27 +27,33 @@ use pocketmine\network\mcpe\NetworkSession; use function base64_decode; +use function file_get_contents; class AvailableActorIdentifiersPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::AVAILABLE_ACTOR_IDENTIFIERS_PACKET; /** - * Hardcoded NBT blob extracted from MCPE vanilla server. + * NBT blob extracted from MCPE vanilla server. * TODO: this needs to be generated dynamically, but this is here for stable backwards compatibility, so we don't care for now. */ - private const HARDCODED_NBT_BLOB = "CgAJBmlkbGlzdArOAQgDYmlkCm1pbmVjcmFmdDoBDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQNbWluZWNyYWZ0Om5wYwMDcmlkhgQBCnN1bW1vbmFibGUAAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA1taW5lY3JhZnQ6Y293AwNyaWQWAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQabWluZWNyYWZ0OndhbmRlcmluZ190cmFkZXIDA3JpZOwBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQRbWluZWNyYWZ0OmJhbGxvb24DA3JpZNYBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQSbWluZWNyYWZ0OmljZV9ib21iAwNyaWTUAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkDm1pbmVjcmFmdDpodXNrAwNyaWReAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQPbWluZWNyYWZ0OnN0cmF5AwNyaWRcAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQPbWluZWNyYWZ0OndpdGNoAwNyaWRaAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQZbWluZWNyYWZ0OnpvbWJpZV92aWxsYWdlcgMDcmlkWAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkD21pbmVjcmFmdDpibGF6ZQMDcmlkVgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkFG1pbmVjcmFmdDptYWdtYV9jdWJlAwNyaWRUAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQPbWluZWNyYWZ0OmdoYXN0AwNyaWRSAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQVbWluZWNyYWZ0OmNhdmVfc3BpZGVyAwNyaWRQAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQUbWluZWNyYWZ0OnNpbHZlcmZpc2gDA3JpZE4BCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBJtaW5lY3JhZnQ6ZW5kZXJtYW4DA3JpZEwBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA9taW5lY3JhZnQ6c2xpbWUDA3JpZEoBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBdtaW5lY3JhZnQ6em9tYmllX3BpZ21hbgMDcmlkSAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkEG1pbmVjcmFmdDpzcGlkZXIDA3JpZEYBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBJtaW5lY3JhZnQ6c2tlbGV0b24DA3JpZEQBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBFtaW5lY3JhZnQ6Y3JlZXBlcgMDcmlkQgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkEG1pbmVjcmFmdDp6b21iaWUDA3JpZEABCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBhtaW5lY3JhZnQ6c2tlbGV0b25faG9yc2UDA3JpZDQBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA5taW5lY3JhZnQ6bXVsZQMDcmlkMgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkEG1pbmVjcmFmdDpkb25rZXkDA3JpZDABCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBFtaW5lY3JhZnQ6ZG9scGhpbgMDcmlkPgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkFm1pbmVjcmFmdDp6b21iaWVfaG9yc2UDA3JpZDYBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBBtaW5lY3JhZnQ6dHVydGxlAwNyaWSUAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkE21pbmVjcmFmdDptb29zaHJvb20DA3JpZCABCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA9taW5lY3JhZnQ6cGFuZGEDA3JpZOIBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQPbWluZWNyYWZ0OmhvcnNlAwNyaWQuAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQQbWluZWNyYWZ0OnNhbG1vbgMDcmlk2gEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA1taW5lY3JhZnQ6cGlnAwNyaWQYAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQSbWluZWNyYWZ0OnZpbGxhZ2VyAwNyaWQeAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQNbWluZWNyYWZ0OmNvZAMDcmlk4AEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBRtaW5lY3JhZnQ6cHVmZmVyZmlzaAMDcmlk2AEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA5taW5lY3JhZnQ6d29sZgMDcmlkHAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkFm1pbmVjcmFmdDp0cm9waWNhbGZpc2gDA3JpZN4BAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQPbWluZWNyYWZ0OnNoZWVwAwNyaWQaAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQRbWluZWNyYWZ0OmRyb3duZWQDA3JpZNwBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQRbWluZWNyYWZ0OmNoaWNrZW4DA3JpZBQBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA9taW5lY3JhZnQ6bGxhbWEDA3JpZDoBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZA9taW5lY3JhZnQ6c3F1aWQDA3JpZCIBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBJtaW5lY3JhZnQ6cGlsbGFnZXIDA3JpZOQBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQUbWluZWNyYWZ0Omlyb25fZ29sZW0DA3JpZCgBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBBtaW5lY3JhZnQ6cmFiYml0AwNyaWQkAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQVbWluZWNyYWZ0OnZpbGxhZ2VyX3YyAwNyaWTmAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkFG1pbmVjcmFmdDpzbm93X2dvbGVtAwNyaWQqAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQNbWluZWNyYWZ0OmJhdAMDcmlkJgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkHG1pbmVjcmFmdDp6b21iaWVfdmlsbGFnZXJfdjIDA3JpZOgBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQQbWluZWNyYWZ0Om9jZWxvdAMDcmlkLAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkDW1pbmVjcmFmdDpjYXQDA3JpZJYBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQUbWluZWNyYWZ0OnBvbGFyX2JlYXIDA3JpZDgBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBBtaW5lY3JhZnQ6cGFycm90AwNyaWQ8AQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQZbWluZWNyYWZ0OndpdGhlcl9za2VsZXRvbgMDcmlkYAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkEm1pbmVjcmFmdDpndWFyZGlhbgMDcmlkYgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkGG1pbmVjcmFmdDplbGRlcl9ndWFyZGlhbgMDcmlkZAEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkFG1pbmVjcmFmdDp2aW5kaWNhdG9yAwNyaWRyAQpzdW1tb25hYmxlAQAIA2JpZAptaW5lY3JhZnQ6AQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkEG1pbmVjcmFmdDpwbGF5ZXIDA3JpZIIEAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQRbWluZWNyYWZ0OnBoYW50b20DA3JpZHQBCnN1bW1vbmFibGUBAAgDYmlkCm1pbmVjcmFmdDoBDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQXbWluZWNyYWZ0OnRyaXBvZF9jYW1lcmEDA3JpZIQEAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQRbWluZWNyYWZ0OnJhdmFnZXIDA3JpZHYBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBBtaW5lY3JhZnQ6d2l0aGVyAwNyaWRoAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQWbWluZWNyYWZ0OmVuZGVyX2RyYWdvbgMDcmlkagEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwEIAmlkEW1pbmVjcmFmdDpzaHVsa2VyAwNyaWRsAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQTbWluZWNyYWZ0OmVuZGVybWl0ZQMDcmlkbgEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkEm1pbmVjcmFmdDptaW5lY2FydAMDcmlkqAEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBltaW5lY3JhZnQ6aG9wcGVyX21pbmVjYXJ0AwNyaWTAAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkFm1pbmVjcmFmdDp0bnRfbWluZWNhcnQDA3JpZMIBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQYbWluZWNyYWZ0OmNoZXN0X21pbmVjYXJ0AwNyaWTEAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkIG1pbmVjcmFmdDpjb21tYW5kX2Jsb2NrX21pbmVjYXJ0AwNyaWTIAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkFW1pbmVjcmFmdDphcm1vcl9zdGFuZAMDcmlkegEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkDm1pbmVjcmFmdDppdGVtAwNyaWSAAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkDW1pbmVjcmFmdDp0bnQDA3JpZIIBAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQXbWluZWNyYWZ0OmZhbGxpbmdfYmxvY2sDA3JpZIQBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQTbWluZWNyYWZ0OnhwX2JvdHRsZQMDcmlkiAEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBBtaW5lY3JhZnQ6eHBfb3JiAwNyaWSKAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkHW1pbmVjcmFmdDpleWVfb2ZfZW5kZXJfc2lnbmFsAwNyaWSMAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkF21pbmVjcmFmdDplbmRlcl9jcnlzdGFsAwNyaWSOAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGG1pbmVjcmFmdDpzaHVsa2VyX2J1bGxldAMDcmlkmAEBCnN1bW1vbmFibGUAAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBZtaW5lY3JhZnQ6ZmlzaGluZ19ob29rAwNyaWSaAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGW1pbmVjcmFmdDpkcmFnb25fZmlyZWJhbGwDA3JpZJ4BAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQPbWluZWNyYWZ0OmFycm93AwNyaWSgAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkEm1pbmVjcmFmdDpzbm93YmFsbAMDcmlkogEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZA1taW5lY3JhZnQ6ZWdnAwNyaWSkAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkEm1pbmVjcmFmdDpwYWludGluZwMDcmlkpgEBCnN1bW1vbmFibGUAAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBhtaW5lY3JhZnQ6dGhyb3duX3RyaWRlbnQDA3JpZJIBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQSbWluZWNyYWZ0OmZpcmViYWxsAwNyaWSqAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkF21pbmVjcmFmdDpzcGxhc2hfcG90aW9uAwNyaWSsAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkFW1pbmVjcmFmdDplbmRlcl9wZWFybAMDcmlkrgEBCnN1bW1vbmFibGUAAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBRtaW5lY3JhZnQ6bGVhc2hfa25vdAMDcmlksAEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBZtaW5lY3JhZnQ6d2l0aGVyX3NrdWxsAwNyaWSyAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkIG1pbmVjcmFmdDp3aXRoZXJfc2t1bGxfZGFuZ2Vyb3VzAwNyaWS2AQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkDm1pbmVjcmFmdDpib2F0AwNyaWS0AQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGG1pbmVjcmFmdDpsaWdodG5pbmdfYm9sdAMDcmlkugEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZBhtaW5lY3JhZnQ6c21hbGxfZmlyZWJhbGwDA3JpZLwBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQUbWluZWNyYWZ0OmxsYW1hX3NwaXQDA3JpZMwBAQpzdW1tb25hYmxlAAAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAAgCaWQbbWluZWNyYWZ0OmFyZWFfZWZmZWN0X2Nsb3VkAwNyaWS+AQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGm1pbmVjcmFmdDpsaW5nZXJpbmdfcG90aW9uAwNyaWTKAQEKc3VtbW9uYWJsZQAACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGm1pbmVjcmFmdDpmaXJld29ya3Nfcm9ja2V0AwNyaWSQAQEKc3VtbW9uYWJsZQEACANiaWQAAQxleHBlcmltZW50YWwAAQtoYXNzcGF3bmVnZwAIAmlkGG1pbmVjcmFmdDpldm9jYXRpb25fZmFuZwMDcmlkzgEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cBCAJpZBttaW5lY3JhZnQ6ZXZvY2F0aW9uX2lsbGFnZXIDA3JpZNABAQpzdW1tb25hYmxlAQAIA2JpZAABDGV4cGVyaW1lbnRhbAABC2hhc3NwYXduZWdnAQgCaWQNbWluZWNyYWZ0OnZleAMDcmlk0gEBCnN1bW1vbmFibGUBAAgDYmlkAAEMZXhwZXJpbWVudGFsAAELaGFzc3Bhd25lZ2cACAJpZA9taW5lY3JhZnQ6YWdlbnQDA3JpZHABCnN1bW1vbmFibGUAAAA="; + private static $NBT_BLOB; /** @var string */ public $namedtag; + public static function init() : void { + self::$NBT_BLOB = file_get_contents(\pocketmine\RESOURCE_PATH . "entity_identifiers.dat"); + } + protected function decodePayload(){ $this->namedtag = $this->getRemaining(); } protected function encodePayload(){ - $this->put($this->namedtag ?? base64_decode(self::HARDCODED_NBT_BLOB)); + $this->put($this->namedtag ?? self::$NBT_BLOB); } public function handle(NetworkSession $session) : bool{ return $session->handleAvailableActorIdentifiers($this); } } +AvailableActorIdentifiersPacket::init(); diff --git a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php index 7a132e991..2dcace9fd 100644 --- a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -26,23 +26,31 @@ #include use pocketmine\network\mcpe\NetworkSession; +use function file_get_contents; class BiomeDefinitionListPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET; - public const HARDCODED_NBT_BLOB = "CgAKDWJhbWJvb19qdW5nbGUFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoTYmFtYm9vX2p1bmdsZV9oaWxscwUIZG93bmZhbGxmZmY/BQt0ZW1wZXJhdHVyZTMzcz8ACgViZWFjaAUIZG93bmZhbGzNzMw+BQt0ZW1wZXJhdHVyZc3MTD8ACgxiaXJjaF9mb3Jlc3QFCGRvd25mYWxsmpkZPwULdGVtcGVyYXR1cmWamRk/AAoSYmlyY2hfZm9yZXN0X2hpbGxzBQhkb3duZmFsbJqZGT8FC3RlbXBlcmF0dXJlmpkZPwAKGmJpcmNoX2ZvcmVzdF9oaWxsc19tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKFGJpcmNoX2ZvcmVzdF9tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKCmNvbGRfYmVhY2gFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw9AAoKY29sZF9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgpjb2xkX3RhaWdhBQhkb3duZmFsbM3MzD4FC3RlbXBlcmF0dXJlAAAAvwAKEGNvbGRfdGFpZ2FfaGlsbHMFCGRvd25mYWxszczMPgULdGVtcGVyYXR1cmUAAAC/AAoSY29sZF90YWlnYV9tdXRhdGVkBQhkb3duZmFsbM3MzD4FC3RlbXBlcmF0dXJlAAAAvwAKD2RlZXBfY29sZF9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8AChFkZWVwX2Zyb3plbl9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAAChNkZWVwX2x1a2V3YXJtX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKCmRlZXBfb2NlYW4FCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAA/AAoPZGVlcF93YXJtX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKBmRlc2VydAUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAACgxkZXNlcnRfaGlsbHMFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoOZGVzZXJ0X211dGF0ZWQFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoNZXh0cmVtZV9oaWxscwUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4AChJleHRyZW1lX2hpbGxzX2VkZ2UFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw+AAoVZXh0cmVtZV9oaWxsc19tdXRhdGVkBQhkb3duZmFsbJqZmT4FC3RlbXBlcmF0dXJlzcxMPgAKGGV4dHJlbWVfaGlsbHNfcGx1c190cmVlcwUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4ACiBleHRyZW1lX2hpbGxzX3BsdXNfdHJlZXNfbXV0YXRlZAUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4ACg1mbG93ZXJfZm9yZXN0BQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKBmZvcmVzdAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzMz8ACgxmb3Jlc3RfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUzMzM/AAoMZnJvemVuX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAAAAKDGZyb3plbl9yaXZlcgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAACgRoZWxsBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlAAAAQAAKDWljZV9tb3VudGFpbnMFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAAAAAoKaWNlX3BsYWlucwUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAAChFpY2VfcGxhaW5zX3NwaWtlcwUIZG93bmZhbGwAAIA/BQt0ZW1wZXJhdHVyZQAAAAAACgZqdW5nbGUFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoLanVuZ2xlX2VkZ2UFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUzM3M/AAoTanVuZ2xlX2VkZ2VfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzcz8ACgxqdW5nbGVfaGlsbHMFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoOanVuZ2xlX211dGF0ZWQFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoTbGVnYWN5X2Zyb3plbl9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAACg5sdWtld2FybV9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgptZWdhX3RhaWdhBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlmpmZPgAKEG1lZ2FfdGFpZ2FfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmWamZk+AAoEbWVzYQUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAACgptZXNhX2JyeWNlBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlAAAAQAAKDG1lc2FfcGxhdGVhdQUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAAChRtZXNhX3BsYXRlYXVfbXV0YXRlZAUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAAChJtZXNhX3BsYXRlYXVfc3RvbmUFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoabWVzYV9wbGF0ZWF1X3N0b25lX211dGF0ZWQFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoPbXVzaHJvb21faXNsYW5kBQhkb3duZmFsbAAAgD8FC3RlbXBlcmF0dXJlZmZmPwAKFW11c2hyb29tX2lzbGFuZF9zaG9yZQUIZG93bmZhbGwAAIA/BQt0ZW1wZXJhdHVyZWZmZj8ACgVvY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgZwbGFpbnMFCGRvd25mYWxszczMPgULdGVtcGVyYXR1cmXNzEw/AAobcmVkd29vZF90YWlnYV9oaWxsc19tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlmpmZPgAKFXJlZHdvb2RfdGFpZ2FfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZQAAgD4ACgVyaXZlcgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACg1yb29mZWRfZm9yZXN0BQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKFXJvb2ZlZF9mb3Jlc3RfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzMz8ACgdzYXZhbm5hBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlmpmZPwAKD3NhdmFubmFfbXV0YXRlZAUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZc3MjD8ACg9zYXZhbm5hX3BsYXRlYXUFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAIA/AAoXc2F2YW5uYV9wbGF0ZWF1X211dGF0ZWQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAIA/AAoLc3RvbmVfYmVhY2gFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw+AAoQc3VuZmxvd2VyX3BsYWlucwUIZG93bmZhbGzNzMw+BQt0ZW1wZXJhdHVyZc3MTD8ACglzd2FtcGxhbmQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmXNzEw/AAoRc3dhbXBsYW5kX211dGF0ZWQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmXNzEw/AAoFdGFpZ2EFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUAAIA+AAoLdGFpZ2FfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUAAIA+AAoNdGFpZ2FfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZQAAgD4ACgd0aGVfZW5kBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKCndhcm1fb2NlYW4FCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAA/AAA="; + /** @var string */ + public static $NBT_BLOB; + /** @var string */ public $namedtag; + public static function init() : void { + self::$NBT_BLOB = file_get_contents(\pocketmine\RESOURCE_PATH . "biome_definitions.dat"); + } + protected function decodePayload(){ $this->namedtag = $this->getRemaining(); } protected function encodePayload(){ - $this->put($this->namedtag ?? self::HARDCODED_NBT_BLOB); + $this->put($this->namedtag ?? self::$NBT_BLOB); } public function handle(NetworkSession $session) : bool{ return $session->handleBiomeDefinitionList($this); } } +BiomeDefinitionListPacket::init(); diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index 05c532d60..c67e031dc 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -54,7 +54,6 @@ public static function init(){ static::registerPacket(new RiderJumpPacket()); static::registerPacket(new UpdateBlockPacket()); static::registerPacket(new AddPaintingPacket()); - static::registerPacket(new ExplodePacket()); static::registerPacket(new LevelSoundEventPacketV1()); static::registerPacket(new LevelEventPacket()); static::registerPacket(new BlockEventPacket()); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 9d8bd8f1b..60b6a2c2d 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -57,22 +57,12 @@ protected function decodePayload(){ $entry->uuid = $this->getUUID(); $entry->entityUniqueId = $this->getEntityUniqueId(); $entry->username = $this->getString(); - - $skinId = $this->getString(); - $skinData = $this->getString(); - $capeData = $this->getString(); - $geometryName = $this->getString(); - $geometryData = $this->getString(); - - $entry->skin = new Skin( - $skinId, - $skinData, - $capeData, - $geometryName, - $geometryData - ); - $entry->xboxUserId = $this->getString(); - $entry->platformChatId = $this->getString(); + $entry->xboxUserId = $this->getString(); + $entry->platformChatId = $this->getString(); + $entry->buildPlatform = $this->getLInt(); + $entry->skin = $this->getSkin(); + $entry->isTeacher = $this->getBool(); + $entry->isHost = $this->getBool(); }else{ $entry->uuid = $this->getUUID(); } @@ -89,13 +79,13 @@ protected function encodePayload(){ $this->putUUID($entry->uuid); $this->putEntityUniqueId($entry->entityUniqueId); $this->putString($entry->username); - $this->putString($entry->skin->getSkinId()); - $this->putString($entry->skin->getSkinData()); - $this->putString($entry->skin->getCapeData()); - $this->putString($entry->skin->getGeometryName()); - $this->putString($entry->skin->getGeometryData()); - $this->putString($entry->xboxUserId); - $this->putString($entry->platformChatId); + $this->putString($entry->xboxUserId); + $this->putString($entry->platformChatId); + $this->putLInt($entry->buildPlatform); + $this->putSkin($entry->skin); + $this->putBool($entry->isTeacher); + $this->putBool($entry->isHost); + }else{ $this->putUUID($entry->uuid); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index ea56e12cb..ee5859f5e 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -34,43 +34,17 @@ class PlayerSkinPacket extends DataPacket{ /** @var UUID */ public $uuid; - /** @var string */ - public $oldSkinName = ""; - /** @var string */ - public $newSkinName = ""; /** @var Skin */ public $skin; - /** @var bool */ - public $premiumSkin = false; protected function decodePayload(){ $this->uuid = $this->getUUID(); - - $skinId = $this->getString(); - $this->newSkinName = $this->getString(); - $this->oldSkinName = $this->getString(); - $skinData = $this->getString(); - $capeData = $this->getString(); - $geometryModel = $this->getString(); - $geometryData = $this->getString(); - - $this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData); - - $this->premiumSkin = $this->getBool(); + $this->skin = $this->getSkin(); } protected function encodePayload(){ $this->putUUID($this->uuid); - - $this->putString($this->skin->getSkinId()); - $this->putString($this->newSkinName); - $this->putString($this->oldSkinName); - $this->putString($this->skin->getSkinData()); - $this->putString($this->skin->getCapeData()); - $this->putString($this->skin->getGeometryName()); - $this->putString($this->skin->getGeometryData()); - - $this->putBool($this->premiumSkin); + $this->putSkin($this->skin); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index 152dd4463..1233f21cf 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -26,164 +26,173 @@ /** * Version numbers and packet IDs for the current Minecraft PE protocol */ -interface ProtocolInfo{ +interface ProtocolInfo +{ - /** - * NOTE TO DEVELOPERS - * Do not waste your time or ours submitting pull requests changing game and/or protocol version numbers. - * Pull requests changing game and/or protocol version numbers will be closed. - * - * This file is generated automatically, do not edit it manually. - */ + /** + * NOTE TO DEVELOPERS + * Do not waste your time or ours submitting pull requests changing game and/or protocol version numbers. + * Pull requests changing game and/or protocol version numbers will be closed. + * + * This file is generated automatically, do not edit it manually. + */ - /** - * Actual Minecraft: PE protocol version - */ - public const CURRENT_PROTOCOL = 361; - /** - * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. - */ - public const MINECRAFT_VERSION = 'v1.12.0'; - /** - * Version number sent to clients in ping responses. - */ - public const MINECRAFT_VERSION_NETWORK = '1.12.0'; + /** + * Actual Minecraft: PE protocol version + */ + public const CURRENT_PROTOCOL = 388; + /** + * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. + */ + public const MINECRAFT_VERSION = 'v1.13.0'; + /** + * Version number sent to clients in ping responses. + */ + public const MINECRAFT_VERSION_NETWORK = '1.13.0'; - public const LOGIN_PACKET = 0x01; - public const PLAY_STATUS_PACKET = 0x02; - public const SERVER_TO_CLIENT_HANDSHAKE_PACKET = 0x03; - public const CLIENT_TO_SERVER_HANDSHAKE_PACKET = 0x04; - public const DISCONNECT_PACKET = 0x05; - public const RESOURCE_PACKS_INFO_PACKET = 0x06; - public const RESOURCE_PACK_STACK_PACKET = 0x07; - public const RESOURCE_PACK_CLIENT_RESPONSE_PACKET = 0x08; - public const TEXT_PACKET = 0x09; - public const SET_TIME_PACKET = 0x0a; - public const START_GAME_PACKET = 0x0b; - public const ADD_PLAYER_PACKET = 0x0c; - public const ADD_ACTOR_PACKET = 0x0d; - public const REMOVE_ACTOR_PACKET = 0x0e; - public const ADD_ITEM_ACTOR_PACKET = 0x0f; + public const LOGIN_PACKET = 0x01; + public const PLAY_STATUS_PACKET = 0x02; + public const SERVER_TO_CLIENT_HANDSHAKE_PACKET = 0x03; + public const CLIENT_TO_SERVER_HANDSHAKE_PACKET = 0x04; + public const DISCONNECT_PACKET = 0x05; + public const RESOURCE_PACKS_INFO_PACKET = 0x06; + public const RESOURCE_PACK_STACK_PACKET = 0x07; + public const RESOURCE_PACK_CLIENT_RESPONSE_PACKET = 0x08; + public const TEXT_PACKET = 0x09; + public const SET_TIME_PACKET = 0x0a; + public const START_GAME_PACKET = 0x0b; + public const ADD_PLAYER_PACKET = 0x0c; + public const ADD_ACTOR_PACKET = 0x0d; + public const REMOVE_ACTOR_PACKET = 0x0e; + public const ADD_ITEM_ACTOR_PACKET = 0x0f; - public const TAKE_ITEM_ACTOR_PACKET = 0x11; - public const MOVE_ACTOR_ABSOLUTE_PACKET = 0x12; - public const MOVE_PLAYER_PACKET = 0x13; - public const RIDER_JUMP_PACKET = 0x14; - public const UPDATE_BLOCK_PACKET = 0x15; - public const ADD_PAINTING_PACKET = 0x16; - public const EXPLODE_PACKET = 0x17; - public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18; - public const LEVEL_EVENT_PACKET = 0x19; - public const BLOCK_EVENT_PACKET = 0x1a; - public const ACTOR_EVENT_PACKET = 0x1b; - public const MOB_EFFECT_PACKET = 0x1c; - public const UPDATE_ATTRIBUTES_PACKET = 0x1d; - public const INVENTORY_TRANSACTION_PACKET = 0x1e; - public const MOB_EQUIPMENT_PACKET = 0x1f; - public const MOB_ARMOR_EQUIPMENT_PACKET = 0x20; - public const INTERACT_PACKET = 0x21; - public const BLOCK_PICK_REQUEST_PACKET = 0x22; - public const ACTOR_PICK_REQUEST_PACKET = 0x23; - public const PLAYER_ACTION_PACKET = 0x24; - public const ACTOR_FALL_PACKET = 0x25; - public const HURT_ARMOR_PACKET = 0x26; - public const SET_ACTOR_DATA_PACKET = 0x27; - public const SET_ACTOR_MOTION_PACKET = 0x28; - public const SET_ACTOR_LINK_PACKET = 0x29; - public const SET_HEALTH_PACKET = 0x2a; - public const SET_SPAWN_POSITION_PACKET = 0x2b; - public const ANIMATE_PACKET = 0x2c; - public const RESPAWN_PACKET = 0x2d; - public const CONTAINER_OPEN_PACKET = 0x2e; - public const CONTAINER_CLOSE_PACKET = 0x2f; - public const PLAYER_HOTBAR_PACKET = 0x30; - public const INVENTORY_CONTENT_PACKET = 0x31; - public const INVENTORY_SLOT_PACKET = 0x32; - public const CONTAINER_SET_DATA_PACKET = 0x33; - public const CRAFTING_DATA_PACKET = 0x34; - public const CRAFTING_EVENT_PACKET = 0x35; - public const GUI_DATA_PICK_ITEM_PACKET = 0x36; - public const ADVENTURE_SETTINGS_PACKET = 0x37; - public const BLOCK_ACTOR_DATA_PACKET = 0x38; - public const PLAYER_INPUT_PACKET = 0x39; - public const LEVEL_CHUNK_PACKET = 0x3a; - public const SET_COMMANDS_ENABLED_PACKET = 0x3b; - public const SET_DIFFICULTY_PACKET = 0x3c; - public const CHANGE_DIMENSION_PACKET = 0x3d; - public const SET_PLAYER_GAME_TYPE_PACKET = 0x3e; - public const PLAYER_LIST_PACKET = 0x3f; - public const SIMPLE_EVENT_PACKET = 0x40; - public const EVENT_PACKET = 0x41; - public const SPAWN_EXPERIENCE_ORB_PACKET = 0x42; - public const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43; - public const MAP_INFO_REQUEST_PACKET = 0x44; - public const REQUEST_CHUNK_RADIUS_PACKET = 0x45; - public const CHUNK_RADIUS_UPDATED_PACKET = 0x46; - public const ITEM_FRAME_DROP_ITEM_PACKET = 0x47; - public const GAME_RULES_CHANGED_PACKET = 0x48; - public const CAMERA_PACKET = 0x49; - public const BOSS_EVENT_PACKET = 0x4a; - public const SHOW_CREDITS_PACKET = 0x4b; - public const AVAILABLE_COMMANDS_PACKET = 0x4c; - public const COMMAND_REQUEST_PACKET = 0x4d; - public const COMMAND_BLOCK_UPDATE_PACKET = 0x4e; - public const COMMAND_OUTPUT_PACKET = 0x4f; - public const UPDATE_TRADE_PACKET = 0x50; - public const UPDATE_EQUIP_PACKET = 0x51; - public const RESOURCE_PACK_DATA_INFO_PACKET = 0x52; - public const RESOURCE_PACK_CHUNK_DATA_PACKET = 0x53; - public const RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x54; - public const TRANSFER_PACKET = 0x55; - public const PLAY_SOUND_PACKET = 0x56; - public const STOP_SOUND_PACKET = 0x57; - public const SET_TITLE_PACKET = 0x58; - public const ADD_BEHAVIOR_TREE_PACKET = 0x59; - public const STRUCTURE_BLOCK_UPDATE_PACKET = 0x5a; - public const SHOW_STORE_OFFER_PACKET = 0x5b; - public const PURCHASE_RECEIPT_PACKET = 0x5c; - public const PLAYER_SKIN_PACKET = 0x5d; - public const SUB_CLIENT_LOGIN_PACKET = 0x5e; - public const AUTOMATION_CLIENT_CONNECT_PACKET = 0x5f; - public const SET_LAST_HURT_BY_PACKET = 0x60; - public const BOOK_EDIT_PACKET = 0x61; - public const NPC_REQUEST_PACKET = 0x62; - public const PHOTO_TRANSFER_PACKET = 0x63; - public const MODAL_FORM_REQUEST_PACKET = 0x64; - public const MODAL_FORM_RESPONSE_PACKET = 0x65; - public const SERVER_SETTINGS_REQUEST_PACKET = 0x66; - public const SERVER_SETTINGS_RESPONSE_PACKET = 0x67; - public const SHOW_PROFILE_PACKET = 0x68; - public const SET_DEFAULT_GAME_TYPE_PACKET = 0x69; - public const REMOVE_OBJECTIVE_PACKET = 0x6a; - public const SET_DISPLAY_OBJECTIVE_PACKET = 0x6b; - public const SET_SCORE_PACKET = 0x6c; - public const LAB_TABLE_PACKET = 0x6d; - public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e; - public const MOVE_ACTOR_DELTA_PACKET = 0x6f; - public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70; - public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71; - public const UPDATE_SOFT_ENUM_PACKET = 0x72; - public const NETWORK_STACK_LATENCY_PACKET = 0x73; + public const TAKE_ITEM_ACTOR_PACKET = 0x11; + public const MOVE_ACTOR_ABSOLUTE_PACKET = 0x12; + public const MOVE_PLAYER_PACKET = 0x13; + public const RIDER_JUMP_PACKET = 0x14; + public const UPDATE_BLOCK_PACKET = 0x15; + public const ADD_PAINTING_PACKET = 0x16; + public const TICK_SYNC_PACKET = 0x17; + public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18; + public const LEVEL_EVENT_PACKET = 0x19; + public const BLOCK_EVENT_PACKET = 0x1a; + public const ACTOR_EVENT_PACKET = 0x1b; + public const MOB_EFFECT_PACKET = 0x1c; + public const UPDATE_ATTRIBUTES_PACKET = 0x1d; + public const INVENTORY_TRANSACTION_PACKET = 0x1e; + public const MOB_EQUIPMENT_PACKET = 0x1f; + public const MOB_ARMOR_EQUIPMENT_PACKET = 0x20; + public const INTERACT_PACKET = 0x21; + public const BLOCK_PICK_REQUEST_PACKET = 0x22; + public const ACTOR_PICK_REQUEST_PACKET = 0x23; + public const PLAYER_ACTION_PACKET = 0x24; + public const ACTOR_FALL_PACKET = 0x25; + public const HURT_ARMOR_PACKET = 0x26; + public const SET_ACTOR_DATA_PACKET = 0x27; + public const SET_ACTOR_MOTION_PACKET = 0x28; + public const SET_ACTOR_LINK_PACKET = 0x29; + public const SET_HEALTH_PACKET = 0x2a; + public const SET_SPAWN_POSITION_PACKET = 0x2b; + public const ANIMATE_PACKET = 0x2c; + public const RESPAWN_PACKET = 0x2d; + public const CONTAINER_OPEN_PACKET = 0x2e; + public const CONTAINER_CLOSE_PACKET = 0x2f; + public const PLAYER_HOTBAR_PACKET = 0x30; + public const INVENTORY_CONTENT_PACKET = 0x31; + public const INVENTORY_SLOT_PACKET = 0x32; + public const CONTAINER_SET_DATA_PACKET = 0x33; + public const CRAFTING_DATA_PACKET = 0x34; + public const CRAFTING_EVENT_PACKET = 0x35; + public const GUI_DATA_PICK_ITEM_PACKET = 0x36; + public const ADVENTURE_SETTINGS_PACKET = 0x37; + public const BLOCK_ACTOR_DATA_PACKET = 0x38; + public const PLAYER_INPUT_PACKET = 0x39; + public const LEVEL_CHUNK_PACKET = 0x3a; + public const SET_COMMANDS_ENABLED_PACKET = 0x3b; + public const SET_DIFFICULTY_PACKET = 0x3c; + public const CHANGE_DIMENSION_PACKET = 0x3d; + public const SET_PLAYER_GAME_TYPE_PACKET = 0x3e; + public const PLAYER_LIST_PACKET = 0x3f; + public const SIMPLE_EVENT_PACKET = 0x40; + public const EVENT_PACKET = 0x41; + public const SPAWN_EXPERIENCE_ORB_PACKET = 0x42; + public const CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43; + public const MAP_INFO_REQUEST_PACKET = 0x44; + public const REQUEST_CHUNK_RADIUS_PACKET = 0x45; + public const CHUNK_RADIUS_UPDATED_PACKET = 0x46; + public const ITEM_FRAME_DROP_ITEM_PACKET = 0x47; + public const GAME_RULES_CHANGED_PACKET = 0x48; + public const CAMERA_PACKET = 0x49; + public const BOSS_EVENT_PACKET = 0x4a; + public const SHOW_CREDITS_PACKET = 0x4b; + public const AVAILABLE_COMMANDS_PACKET = 0x4c; + public const COMMAND_REQUEST_PACKET = 0x4d; + public const COMMAND_BLOCK_UPDATE_PACKET = 0x4e; + public const COMMAND_OUTPUT_PACKET = 0x4f; + public const UPDATE_TRADE_PACKET = 0x50; + public const UPDATE_EQUIP_PACKET = 0x51; + public const RESOURCE_PACK_DATA_INFO_PACKET = 0x52; + public const RESOURCE_PACK_CHUNK_DATA_PACKET = 0x53; + public const RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x54; + public const TRANSFER_PACKET = 0x55; + public const PLAY_SOUND_PACKET = 0x56; + public const STOP_SOUND_PACKET = 0x57; + public const SET_TITLE_PACKET = 0x58; + public const ADD_BEHAVIOR_TREE_PACKET = 0x59; + public const STRUCTURE_BLOCK_UPDATE_PACKET = 0x5a; + public const SHOW_STORE_OFFER_PACKET = 0x5b; + public const PURCHASE_RECEIPT_PACKET = 0x5c; + public const PLAYER_SKIN_PACKET = 0x5d; + public const SUB_CLIENT_LOGIN_PACKET = 0x5e; + public const AUTOMATION_CLIENT_CONNECT_PACKET = 0x5f; + public const SET_LAST_HURT_BY_PACKET = 0x60; + public const BOOK_EDIT_PACKET = 0x61; + public const NPC_REQUEST_PACKET = 0x62; + public const PHOTO_TRANSFER_PACKET = 0x63; + public const MODAL_FORM_REQUEST_PACKET = 0x64; + public const MODAL_FORM_RESPONSE_PACKET = 0x65; + public const SERVER_SETTINGS_REQUEST_PACKET = 0x66; + public const SERVER_SETTINGS_RESPONSE_PACKET = 0x67; + public const SHOW_PROFILE_PACKET = 0x68; + public const SET_DEFAULT_GAME_TYPE_PACKET = 0x69; + public const REMOVE_OBJECTIVE_PACKET = 0x6a; + public const SET_DISPLAY_OBJECTIVE_PACKET = 0x6b; + public const SET_SCORE_PACKET = 0x6c; + public const LAB_TABLE_PACKET = 0x6d; + public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e; + public const MOVE_ACTOR_DELTA_PACKET = 0x6f; + public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70; + public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71; + public const UPDATE_SOFT_ENUM_PACKET = 0x72; + public const NETWORK_STACK_LATENCY_PACKET = 0x73; - public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75; - public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76; - public const AVAILABLE_ACTOR_IDENTIFIERS_PACKET = 0x77; - public const LEVEL_SOUND_EVENT_PACKET_V2 = 0x78; - public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79; - public const BIOME_DEFINITION_LIST_PACKET = 0x7a; - public const LEVEL_SOUND_EVENT_PACKET = 0x7b; - public const LEVEL_EVENT_GENERIC_PACKET = 0x7c; - public const LECTERN_UPDATE_PACKET = 0x7d; - public const VIDEO_STREAM_CONNECT_PACKET = 0x7e; - public const ADD_ENTITY_PACKET = 0x7f; - public const REMOVE_ENTITY_PACKET = 0x80; - public const CLIENT_CACHE_STATUS_PACKET = 0x81; - public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x82; - public const MAP_CREATE_LOCKED_COPY_PACKET = 0x83; - public const STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET = 0x84; - public const STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET = 0x85; - public const UPDATE_BLOCK_PROPERTIES_PACKET = 0x86; - public const CLIENT_CACHE_BLOB_STATUS_PACKET = 0x87; - public const CLIENT_CACHE_MISS_RESPONSE_PACKET = 0x88; + public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75; + public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76; + public const AVAILABLE_ACTOR_IDENTIFIERS_PACKET = 0x77; + public const LEVEL_SOUND_EVENT_PACKET_V2 = 0x78; + public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79; + public const BIOME_DEFINITION_LIST_PACKET = 0x7a; + public const LEVEL_SOUND_EVENT_PACKET = 0x7b; + public const LEVEL_EVENT_GENERIC_PACKET = 0x7c; + public const LECTERN_UPDATE_PACKET = 0x7d; + public const VIDEO_STREAM_CONNECT_PACKET = 0x7e; + public const ADD_ENTITY_PACKET = 0x7f; + public const REMOVE_ENTITY_PACKET = 0x80; + public const CLIENT_CACHE_STATUS_PACKET = 0x81; + public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x82; + public const MAP_CREATE_LOCKED_COPY_PACKET = 0x83; + public const STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET = 0x84; + public const STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET = 0x85; + public const UPDATE_BLOCK_PROPERTIES_PACKET = 0x86; + public const CLIENT_CACHE_BLOB_STATUS_PACKET = 0x87; + public const CLIENT_CACHE_MISS_RESPONSE_PACKET = 0x88; + public const EDUCATION_SETTINGS_PACKET = 0x89; + public const EMOTE_PACKET = 0x8a; + public const MULTIPLAYER_SETTINGS_PACKET = 0x8b; + public const SETTINGS_COMMAND_PACKET = 0x8c; + public const ANVIL_DAMAGE_PACKET = 0x8d; + public const COMPLETED_USING_ITEM_PACKET = 0x8e; + public const NETWORK_SETTINGS_PACKET = 0x8f; + public const PLAYER_AUTH_INPUT_PACKET = 0x90; } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 81bdfe702..b5d6c4543 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -46,7 +46,7 @@ class ResourcePackDataInfoPacket extends DataPacket{ /** @var bool */ public $isPremium = false; /** @var int */ - public $packType = ResourcePackType::RESOURCES; //TODO: check the values for this + public $packType = ResourcePackType::ADDON; //TODO: check the values for this protected function decodePayload(){ $this->packId = $this->getString(); diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index b13e7bcb7..564ee47ab 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -32,15 +32,27 @@ class RespawnPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; + public const STATE_SEARCHING_FOR_SPAWN = 0; + public const STATE_READY_TO_SPAWN = 1; + public const STATE_CLIENT_READY_TO_SPAWN = 2; + /** @var Vector3 */ public $position; + /** @var int */ + public $respawnState = self::STATE_SEARCHING_FOR_SPAWN; + /** @var int */ + public $runtimeEntityId; //??? protected function decodePayload(){ $this->position = $this->getVector3(); + $this->respawnState = $this->getByte(); + $this->runtimeEntityId = $this->getEntityRuntimeId(); } protected function encodePayload(){ $this->putVector3($this->position); + $this->putByte($this->respawnState); + // $this->putEntityRuntimeId($this->runtimeEntityId); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 557dee7ca..52e8790d8 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -27,6 +27,10 @@ use pocketmine\math\Vector3; +use pocketmine\nbt\NetworkLittleEndianNBTStream; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; @@ -129,6 +133,8 @@ class StartGamePacket extends DataPacket{ public $isWorldTemplateOptionLocked = false; /** @var bool */ public $onlySpawnV1Villagers = false; + /** @var string */ + public $vanillaVersion = ProtocolInfo::MINECRAFT_VERSION_NETWORK; /** @var string */ public $levelId = ""; //base64 string, usually the same as world folder name in vanilla @@ -138,6 +144,8 @@ class StartGamePacket extends DataPacket{ public $premiumWorldTemplateId = ""; /** @var bool */ public $isTrial = false; + /** @var bool */ + public $isMovementServerAuthoritative = false; /** @var int */ public $currentTick = 0; //only used if isTrial is true /** @var int */ @@ -192,11 +200,13 @@ protected function decodePayload(){ $this->isFromWorldTemplate = $this->getBool(); $this->isWorldTemplateOptionLocked = $this->getBool(); $this->onlySpawnV1Villagers = $this->getBool(); + $this->vanillaVersion = $this->getString(); $this->levelId = $this->getString(); $this->worldName = $this->getString(); $this->premiumWorldTemplateId = $this->getString(); $this->isTrial = $this->getBool(); + $this->isMovementServerAuthoritative = $this->getBool(); $this->currentTick = $this->getLLong(); $this->enchantmentSeed = $this->getVarInt(); @@ -262,11 +272,13 @@ protected function encodePayload(){ $this->putBool($this->isFromWorldTemplate); $this->putBool($this->isWorldTemplateOptionLocked); $this->putBool($this->onlySpawnV1Villagers); + $this->putString($this->vanillaVersion); $this->putString($this->levelId); $this->putString($this->worldName); $this->putString($this->premiumWorldTemplateId); $this->putBool($this->isTrial); + $this->putBool($this->isMovementServerAuthoritative); $this->putLLong($this->currentTick); $this->putVarInt($this->enchantmentSeed); @@ -293,14 +305,21 @@ protected function encodePayload(){ } private static function serializeBlockTable(array $table) : string{ - $stream = new NetworkBinaryStream(); - $stream->putUnsignedVarInt(count($table)); + $states = new ListTag(); foreach($table as $v){ - $stream->putString($v["name"]); - $stream->putLShort($v["data"]); - $stream->putLShort($v["legacy_id"]); + $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 $stream->getBuffer(); + + ($stream = new NetworkLittleEndianNBTStream())->writeTag($states); + + return $stream->buffer; } private static function serializeItemTable(array $table) : string{ @@ -310,6 +329,7 @@ private static function serializeItemTable(array $table) : string{ $stream->putString($name); $stream->putLShort($legacyId); } + return $stream->getBuffer(); } diff --git a/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php b/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php index b8b14f0d8..aae6de757 100644 --- a/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php @@ -34,12 +34,18 @@ class PlayerListEntry{ public $entityUniqueId; /** @var string */ public $username; - /** @var Skin */ - public $skin; /** @var string */ public $xboxUserId; /** @var string */ public $platformChatId = ""; + /** @var int */ + public $buildPlatform = -1; + /** @var Skin */ + public $skin; + /** @var bool */ + public $isTeacher = false; + /** @var bool */ + public $isHost = false; public static function createRemovalEntry(UUID $uuid) : PlayerListEntry{ $entry = new PlayerListEntry(); diff --git a/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php b/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php index 9efaced08..b1d806e15 100644 --- a/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php +++ b/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php @@ -30,9 +30,13 @@ private function __construct(){ } public const INVALID = 0; - public const RESOURCES = 1; - public const BEHAVIORS = 2; - public const WORLD_TEMPLATE = 3; - public const ADDON = 4; //scripts? - public const SKINS = 5; + public const ADDON = 1; + public const CACHED = 2; + public const COPY_PROTECTED = 3; + public const BEHAVIOR = 4; + public const PERSONA_PIECE = 5; + public const RESOURCE = 6; + public const SKINS = 7; + public const WORLD_TEMPLATE = 8; + public const COUNT = 9; } diff --git a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php index 9ba73cbb4..7bf1ea905 100644 --- a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -24,9 +24,12 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\block\BlockIds; +use pocketmine\nbt\BigEndianNBTStream; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\BinaryDataException; +use RuntimeException; use function file_get_contents; use function getmypid; -use function json_decode; use function mt_rand; use function mt_srand; use function shuffle; @@ -48,23 +51,28 @@ private function __construct(){ } public static function init() : void{ - $legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/block_id_map.json"), true); + try{ + /** @var CompoundTag $tag */ + $tag = (new BigEndianNBTStream())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "runtime_block_states.dat")); + }catch(BinaryDataException $e){ + throw new RuntimeException("", 0, $e); + } - $compressedTable = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/required_block_states.json"), true); $decompressed = []; - foreach($compressedTable as $prefix => $entries){ - foreach($entries as $shortStringId => $states){ - foreach($states as $state){ - $name = "$prefix:$shortStringId"; - $decompressed[] = [ - "name" => $name, - "data" => $state, - "legacy_id" => $legacyIdMap[$name] - ]; - } - } + $states = $tag->getListTag("Palette"); + foreach($states as $state){ + /** @var CompoundTag $state */ + $block = $state->getCompoundTag("block"); + + $decompressed[] = [ + "name" => $block->getString("name"), + "states" => $block->getCompoundTag("states"), + "data" => $state->getShort("meta"), + "legacy_id" => $state->getShort("id"), + ]; } + self::$bedrockKnownStates = self::randomizeTable($decompressed); foreach(self::$bedrockKnownStates as $k => $obj){ @@ -91,6 +99,7 @@ private static function randomizeTable(array $table) : array{ mt_srand(getmypid() ?: 0); //Use a seed which is the same on all threads. This isn't a secure seed, but we don't care. shuffle($table); mt_srand($postSeed); //restore a good quality seed that isn't dependent on PID + return $table; } @@ -116,6 +125,7 @@ public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ */ public static function fromStaticRuntimeId(int $runtimeId) : array{ $v = self::$runtimeToLegacyMap[$runtimeId]; + return [$v >> 4, $v & 0xf]; } @@ -130,5 +140,7 @@ private static function registerMapping(int $staticRuntimeId, int $legacyId, int public static function getBedrockKnownStates() : array{ return self::$bedrockKnownStates; } + } + RuntimeBlockMapping::init(); diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index ee92644b3..1660ce96e 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -265,14 +265,6 @@ public function loadPlugins(string $directory, array $newLoaders = null){ continue; } - if(!$this->isCompatibleApi(...$description->getCompatibleApis())){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ - $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleAPI", [implode(", ", $description->getCompatibleApis())]) - ])); - continue; - } - if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index c7026a46f..0cc533586 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -62,10 +62,10 @@ public function run(){ gc_enable(); if($this->memoryLimit > 0){ - ini_set('memory_limit', $this->memoryLimit . 'M'); + //ini_set('memory_limit', $this->memoryLimit . 'M'); $this->logger->debug("Set memory limit to " . $this->memoryLimit . " MB"); }else{ - ini_set('memory_limit', '-1'); + //ini_set('memory_limit', '-1'); $this->logger->debug("No memory limit set"); } } diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php new file mode 100644 index 000000000..7edd523f7 --- /dev/null +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -0,0 +1,163 @@ +getProperty("anonymous-statistics.host", "stats.pocketmine.net") . "/"; + + $data = []; + $data["uniqueServerId"] = $server->getServerUniqueId()->toString(); + $data["uniqueMachineId"] = Utils::getMachineUniqueId()->toString(); + $data["uniqueRequestId"] = UUID::fromData($server->getServerUniqueId()->toString(), microtime(false))->toString(); + + switch($type){ + case self::TYPE_OPEN: + $data["event"] = "open"; + + $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + + $data["server"] = [ + "port" => $server->getPort(), + "software" => $server->getName(), + "fullVersion" => $version->getFullVersion(true), + "version" => $version->getFullVersion(false), + "build" => $version->getBuild(), + "api" => $server->getApiVersion(), + "minecraftVersion" => $server->getVersion(), + "protocol" => ProtocolInfo::CURRENT_PROTOCOL + ]; + + $data["system"] = [ + "operatingSystem" => Utils::getOS(), + "cores" => Utils::getCoreCount(), + "phpVersion" => PHP_VERSION, + "machine" => php_uname("a"), + "release" => php_uname("r"), + "platform" => php_uname("i") + ]; + + $data["players"] = [ + "count" => 0, + "limit" => $server->getMaxPlayers() + ]; + + $plugins = []; + + foreach($server->getPluginManager()->getPlugins() as $p){ + $d = $p->getDescription(); + + $plugins[$d->getName()] = [ + "name" => $d->getName(), + "version" => $d->getVersion(), + "enabled" => $p->isEnabled() + ]; + } + + $data["plugins"] = $plugins; + + break; + case self::TYPE_STATUS: + $data["event"] = "status"; + + $data["server"] = [ + "ticksPerSecond" => $server->getTicksPerSecondAverage(), + "tickUsage" => $server->getTickUsageAverage(), + "ticks" => $server->getTick() + ]; + + + //This anonymizes the user ids so they cannot be reversed to the original + foreach($playerList as $k => $v){ + $playerList[$k] = md5($v); + } + + $players = []; + foreach($server->getOnlinePlayers() as $p){ + if($p->isOnline()){ + $players[] = md5($p->getUniqueId()->toBinary()); + } + } + + $data["players"] = [ + "count" => count($players), + "limit" => $server->getMaxPlayers(), + "currentList" => $players, + "historyList" => array_values($playerList) + ]; + + $info = Utils::getMemoryUsage(true); + $data["system"] = [ + "mainMemory" => $info[0], + "totalMemory" => $info[1], + "availableMemory" => $info[2], + "threadCount" => Utils::getThreadCount() + ]; + + break; + case self::TYPE_CLOSE: + $data["event"] = "close"; + $data["crashing"] = $server->isRunning(); + break; + } + + $this->endpoint = $endpoint . "api/post"; + $this->data = json_encode($data/*, JSON_PRETTY_PRINT*/); + } + + public function onRun(){ + Internet::postURL($this->endpoint, $this->data, 5, [ + "Content-Type: application/json", + "Content-Length: " . strlen($this->data) + ]); + } +} diff --git a/src/pocketmine/utils/Internet.php b/src/pocketmine/utils/Internet.php new file mode 100644 index 000000000..7f6b2216a --- /dev/null +++ b/src/pocketmine/utils/Internet.php @@ -0,0 +1,142 @@ + value] map + * @param callable|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle. + * + * @return array a plain array of three [result body : string, headers : array[], HTTP response code : int]. Headers are grouped by requests with strtolower(header name) as keys and header value as values + * + * @throws InternetException if a cURL error occurs + */ + public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], callable $onSuccess = null){ + + } +} diff --git a/src/pocketmine/utils/InternetException.php b/src/pocketmine/utils/InternetException.php new file mode 100644 index 000000000..bc93512b0 --- /dev/null +++ b/src/pocketmine/utils/InternetException.php @@ -0,0 +1,28 @@ + $v){ - if($v == "00-00-00-00-00-00"){ - unset($matches[1][$i]); - } - } - $machine .= implode(" ", $matches[1]); //Mac Addresses - } - }elseif($os === "linux"){ + if($os === "linux"){ if(file_exists("/etc/machine-id")){ $machine .= file_get_contents("/etc/machine-id"); }else{ @@ -521,27 +510,7 @@ public static function javaStringHash(string $string) : int{ * @return int process exit code */ public static function execute(string $command, string &$stdout = null, string &$stderr = null) : int{ - $process = proc_open($command, [ - ["pipe", "r"], - ["pipe", "w"], - ["pipe", "w"] - ], $pipes); - - if($process === false){ - $stderr = "Failed to open process"; - $stdout = ""; - - return -1; - } - - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - - foreach($pipes as $p){ - fclose($p); - } - - return proc_close($process); + return 0; } public static function decodeJWT(string $token) : array{