diff --git a/changelogs/3.11.md b/changelogs/3.11.md index 3e471a43c..0ed526394 100644 --- a/changelogs/3.11.md +++ b/changelogs/3.11.md @@ -79,3 +79,19 @@ Plugin developers should **only** update their required API to this version if y - `ThreadManager` is now lazily initialized. - Removed raw NBT storage from `Item` internals. The following methods are now deprecated: - `Item::setCompoundTag()` + +# 3.11.7 +- Build system: Fixed crash reports of Jenkins builds being rejected by the crash archive as invalid. +- Introduced a new dependency on `pocketmine/log-pthreads`, which contains classes separated from `pocketmine/log`. +- Fixed minimum composer stability preventing any newer version of `pocketmine/pocketmine-mp` being installed than 3.3.4 by replacing `daverandom/callback-validator` with [`pocketmine/callback-validator`](https://github.com/pmmp/CallbackValidator). +- Fixed every player seeing eating particles when any player eats. +- Fixed setting held item not working during `BlockBreakEvent`, `PlayerInteractEvent` and `EntityDamageEvent`. +- Fixed some incorrect documented types in `PlayerQuitEvent` reported by PHPStan. +- Fixed documentation of `Item->pop()` return value. +- Fixed server crash on encountering corrupted compressed data stored in region files. +- Protocol: Split screen header is now properly accounted for during decoding. Note that split screen is still not supported natively, but their packets can be decoded properly now. +- Protocol: Fixed wrong order of fields in `UpdateTradePacket`. +- Protocol: Fixed loss of `fullSkinId` when decoding network skins. +- Fixed RCON not being able to bind to port after a fast server restart. + + diff --git a/changelogs/3.12.md b/changelogs/3.12.md new file mode 100644 index 000000000..037d691a0 --- /dev/null +++ b/changelogs/3.12.md @@ -0,0 +1,11 @@ +**For Minecraft: Bedrock Edition 1.14.60** + +### Note about API versions +Plugins which don't touch the protocol and compatible with any previous 3.x.y version will also run on these releases and do not need API bumps. +Plugin developers should **only** update their required API to this version if you need the changes in this build. + +**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do. + +# 3.12.0 +- Added support for Minecraft: Bedrock Edition 1.14.60 +- Removed compatibility with 1.14.0-1.14.30 diff --git a/composer.lock b/composer.lock index 5bb800d84..78a37fed9 100644 --- a/composer.lock +++ b/composer.lock @@ -276,16 +276,16 @@ }, { "name": "pocketmine/nbt", - "version": "0.2.13", + "version": "0.2.14", "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "6fc56f864a5375471f6e2d0f9f89f2462a1d8433" + "reference": "b31dca98443328c4bab76dc1b84c1473c79be20e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/6fc56f864a5375471f6e2d0f9f89f2462a1d8433", - "reference": "6fc56f864a5375471f6e2d0f9f89f2462a1d8433", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/b31dca98443328c4bab76dc1b84c1473c79be20e", + "reference": "b31dca98443328c4bab76dc1b84c1473c79be20e", "shasum": "" }, "require": { @@ -295,8 +295,8 @@ "pocketmine/binaryutils": "^0.1.9" }, "require-dev": { - "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "^0.12.8" + "irstea/phpunit-shim": "^7.5 || ^8.0", + "phpstan/phpstan": "^0.12.11" }, "type": "library", "autoload": { @@ -309,7 +309,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-01-28T17:03:46+00:00" + "time": "2020-04-15T11:29:25+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b1b0cbf2a..4cf952e07 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -146,6 +146,8 @@ use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\DimensionIds; +use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; +use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\types\SkinAnimation; @@ -1859,6 +1861,16 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $animations[] = new SkinAnimation(new SkinImage($animation["ImageHeight"], $animation["ImageWidth"], base64_decode($animation["Image"], true)), $animation["Type"], $animation["Frames"]); } + $personaPieces = []; + foreach($packet->clientData["PersonaPieces"] as $piece){ + $personaPieces[] = new PersonaSkinPiece($piece["PieceId"], $piece["PieceType"], $piece["PackId"], $piece["IsDefault"], $piece["ProductId"]); + } + + $pieceTintColors = []; + foreach($packet->clientData["PieceTintColors"] as $tintColor){ + $pieceTintColors[] = new PersonaPieceTintColor($tintColor["PieceType"], $tintColor["Colors"]); + } + $skinData = new SkinData( $packet->clientData["SkinId"], base64_decode($packet->clientData["SkinResourcePatch"] ?? "", true), @@ -1870,7 +1882,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $packet->clientData["PremiumSkin"] ?? false, $packet->clientData["PersonaSkin"] ?? false, $packet->clientData["CapeOnClassicSkin"] ?? false, - $packet->clientData["CapeId"] ?? "" + $packet->clientData["CapeId"] ?? "", + null, + $packet->clientData["ArmSize"] ?? SkinData::ARM_SIZE_WIDE, + $packet->clientData["SkinColor"] ?? "", + $personaPieces, + $pieceTintColors, + true ); $skin = SkinAdapterSingleton::get()->fromSkinData($skinData); diff --git a/src/pocketmine/VersionInfo.php b/src/pocketmine/VersionInfo.php index db462770c..b5f3f7d27 100644 --- a/src/pocketmine/VersionInfo.php +++ b/src/pocketmine/VersionInfo.php @@ -33,6 +33,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ const _VERSION_INFO_INCLUDED = true; const NAME = "PocketMine-MP"; -const BASE_VERSION = "3.11.7"; +const BASE_VERSION = "3.12.1"; const IS_DEVELOPMENT_BUILD = true; const BUILD_NUMBER = 0; diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 627a6eb15..9d9b121ef 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -37,9 +37,12 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; +use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\network\mcpe\protocol\types\SkinImage; +use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; @@ -98,8 +101,35 @@ class NetworkBinaryStream extends BinaryStream{ $capeOnClassic = $this->getBool(); $capeId = $this->getString(); $fullSkinId = $this->getString(); + $armSize = $this->getString(); + $skinColor = $this->getString(); + $personaPieceCount = $this->getLInt(); + $personaPieces = []; + for($i = 0; $i < $personaPieceCount; ++$i){ + $personaPieces[] = new PersonaSkinPiece( + $pieceId = $this->getString(), + $pieceType = $this->getString(), + $packId = $this->getString(), + $isDefaultPiece = $this->getBool(), + $productId = $this->getString() + ); + } + $pieceTintColorCount = $this->getLInt(); + $pieceTintColors = []; + for($i = 0; $i < $pieceTintColorCount; ++$i){ + $pieceType = $this->getString(); + $colorCount = $this->getLInt(); + $colors = []; + for($j = 0; $j < $colorCount; ++$j){ + $colors[] = $this->getString(); + } + $pieceTintColors[] = new PersonaPieceTintColor( + $pieceType, + $colors + ); + } - return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId); + return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId, $armSize, $skinColor, $personaPieces, $pieceTintColors); } /** @@ -123,6 +153,24 @@ class NetworkBinaryStream extends BinaryStream{ $this->putBool($skin->isPersonaCapeOnClassic()); $this->putString($skin->getCapeId()); $this->putString($skin->getFullSkinId()); + $this->putString($skin->getArmSize()); + $this->putString($skin->getSkinColor()); + $this->putLInt(count($skin->getPersonaPieces())); + foreach($skin->getPersonaPieces() as $piece){ + $this->putString($piece->getPieceId()); + $this->putString($piece->getPieceType()); + $this->putString($piece->getPackId()); + $this->putBool($piece->isDefaultPiece()); + $this->putString($piece->getProductId()); + } + $this->putLInt(count($skin->getPieceTintColors())); + foreach($skin->getPieceTintColors() as $tint){ + $this->putString($tint->getPieceType()); + $this->putLInt(count($tint->getColors())); + foreach($tint->getColors() as $color){ + $this->putString($color); + } + } } private function getSkinImage() : SkinImage{ @@ -655,6 +703,7 @@ class NetworkBinaryStream extends BinaryStream{ $result->mirror = $this->getByte(); $result->integrityValue = $this->getFloat(); $result->integritySeed = $this->getInt(); + $result->pivot = $this->getVector3(); return $result; } @@ -673,5 +722,34 @@ class NetworkBinaryStream extends BinaryStream{ $this->putByte($structureSettings->mirror); $this->putFloat($structureSettings->integrityValue); $this->putInt($structureSettings->integritySeed); + $this->putVector3($structureSettings->pivot); + } + + protected function getStructureEditorData() : StructureEditorData{ + $result = new StructureEditorData(); + + $result->structureName = $this->getString(); + $result->structureDataField = $this->getString(); + + $result->includePlayers = $this->getBool(); + $result->showBoundingBox = $this->getBool(); + + $result->structureBlockType = $this->getVarInt(); + $result->structureSettings = $this->getStructureSettings(); + $result->structureRedstoneSaveMove = $this->getVarInt(); + + return $result; + } + + protected function putStructureEditorData(StructureEditorData $structureEditorData) : void{ + $this->putString($structureEditorData->structureName); + $this->putString($structureEditorData->structureDataField); + + $this->putBool($structureEditorData->includePlayers); + $this->putBool($structureEditorData->showBoundingBox); + + $this->putVarInt($structureEditorData->structureBlockType); + $this->putStructureSettings($structureEditorData->structureSettings); + $this->putVarInt($structureEditorData->structureRedstoneSaveMove); } } diff --git a/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php b/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php index 3d4caa299..fbb6887fa 100644 --- a/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php @@ -30,10 +30,11 @@ use pocketmine\network\mcpe\NetworkSession; class ActorEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET; + public const JUMP = 1; public const HURT_ANIMATION = 2; public const DEATH_ANIMATION = 3; public const ARM_SWING = 4; - + public const STOP_ATTACK = 5; public const TAME_FAIL = 6; public const TAME_SUCCESS = 7; public const SHAKE_WET = 8; @@ -50,16 +51,18 @@ class ActorEventPacket extends DataPacket{ public const IRON_GOLEM_OFFER_FLOWER = 19; public const IRON_GOLEM_WITHDRAW_FLOWER = 20; public const LOVE_PARTICLES = 21; //breeding - + public const VILLAGER_ANGRY = 22; + public const VILLAGER_HAPPY = 23; public const WITCH_SPELL_PARTICLES = 24; public const FIREWORK_PARTICLES = 25; - + public const IN_LOVE_PARTICLES = 26; public const SILVERFISH_SPAWN_ANIMATION = 27; - + public const GUARDIAN_ATTACK = 28; public const WITCH_DRINK_POTION = 29; public const WITCH_THROW_POTION = 30; public const MINECART_TNT_PRIME_FUSE = 31; - + public const CREEPER_PRIME_FUSE = 32; + public const AIR_SUPPLY_EXPIRED = 33; public const PLAYER_ADD_XP_LEVELS = 34; public const ELDER_GUARDIAN_CURSE = 35; public const AGENT_ARM_SWING = 36; @@ -79,6 +82,11 @@ class ActorEventPacket extends DataPacket{ public const ENTITY_SPAWN = 67; //used for MinecraftEventing stuff, not needed public const DRAGON_PUKE = 68; //they call this puke particles public const ITEM_ENTITY_MERGE = 69; + public const START_SWIM = 70; + public const BALLOON_POP = 71; + public const TREASURE_HUNT = 72; + public const AGENT_SUMMON = 73; + public const CHARGED_CROSSBOW = 74; //TODO: add more events diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 75f67a471..38c14ceb8 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -34,6 +34,7 @@ class AnimatePacket extends DataPacket{ public const ACTION_STOP_SLEEP = 3; public const ACTION_CRITICAL_HIT = 4; + public const ACTION_MAGICAL_CRITICAL_HIT = 5; public const ACTION_ROW_RIGHT = 128; public const ACTION_ROW_LEFT = 129; diff --git a/src/pocketmine/network/mcpe/protocol/InteractPacket.php b/src/pocketmine/network/mcpe/protocol/InteractPacket.php index 52b0ca4e4..a2f7d2fe6 100644 --- a/src/pocketmine/network/mcpe/protocol/InteractPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InteractPacket.php @@ -32,7 +32,7 @@ class InteractPacket extends DataPacket{ public const ACTION_LEAVE_VEHICLE = 3; public const ACTION_MOUSEOVER = 4; - + public const ACTION_OPEN_NPC = 5; public const ACTION_OPEN_INVENTORY = 6; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php index 8f45bcc56..54a3fd346 100644 --- a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php +++ b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php @@ -30,8 +30,12 @@ use pocketmine\network\mcpe\NetworkSession; class LabTablePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; + public const TYPE_START_COMBINE = 0; + public const TYPE_START_REACTION = 1; + public const TYPE_RESET = 2; + /** @var int */ - public $uselessByte; //0 for client -> server, 1 for server -> client. Seems useless. + public $type; /** @var int */ public $x; @@ -44,13 +48,13 @@ class LabTablePacket extends DataPacket{ public $reactionType; protected function decodePayload(){ - $this->uselessByte = $this->getByte(); + $this->type = $this->getByte(); $this->getSignedBlockPosition($this->x, $this->y, $this->z); $this->reactionType = $this->getByte(); } protected function encodePayload(){ - $this->putByte($this->uselessByte); + $this->putByte($this->type); $this->putSignedBlockPosition($this->x, $this->y, $this->z); $this->putByte($this->reactionType); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index de15f2825..44646bf52 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -67,6 +67,11 @@ class PlayerListPacket extends DataPacket{ $this->entries[$i] = $entry; } + if($this->type === self::TYPE_ADD){ + for($i = 0; $i < $count; ++$i){ + $this->entries[$i]->skinData->setVerified($this->getBool()); + } + } } protected function encodePayload(){ @@ -87,6 +92,11 @@ class PlayerListPacket extends DataPacket{ $this->putUUID($entry->uuid); } } + if($this->type === self::TYPE_ADD){ + foreach($this->entries as $entry){ + $this->putBool($entry->skinData->isVerified()); + } + } } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index f197386b4..661f73e03 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -46,6 +46,7 @@ class PlayerSkinPacket extends DataPacket{ $this->skin = $this->getSkin(); $this->newSkinName = $this->getString(); $this->oldSkinName = $this->getString(); + $this->skin->setVerified($this->getBool()); } protected function encodePayload(){ @@ -53,6 +54,7 @@ class PlayerSkinPacket extends DataPacket{ $this->putSkin($this->skin); $this->putString($this->newSkinName); $this->putString($this->oldSkinName); + $this->putBool($this->skin->isVerified()); } 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 8d08df6c3..a020149b8 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -37,11 +37,11 @@ interface ProtocolInfo{ */ /** Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 389; + public const CURRENT_PROTOCOL = 390; /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.14.0'; + public const MINECRAFT_VERSION = 'v1.14.60'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.14.0'; + public const MINECRAFT_VERSION_NETWORK = '1.14.60'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php index ef4febf1f..fa748f2a8 100644 --- a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -26,16 +26,32 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\types\StructureEditorData; -class StructureBlockUpdatePacket extends DataPacket{ +class StructureBlockUpdatePacket extends DataPacket/* implements ServerboundPacket*/{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; + /** @var int */ + public $x; + /** @var int */ + public $y; + /** @var int */ + public $z; + /** @var StructureEditorData */ + public $structureEditorData; + /** @var bool */ + public $isPowered; + protected function decodePayload(){ - //TODO + $this->getBlockPosition($this->x, $this->y, $this->z); + $this->structureEditorData = $this->getStructureEditorData(); + $this->isPowered = $this->getBool(); } protected function encodePayload(){ - //TODO + $this->putBlockPosition($this->x, $this->y, $this->z); + $this->putStructureEditorData($this->structureEditorData); + $this->putBool($this->isPowered); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php index b32d3eca7..7923dae7c 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -35,7 +35,7 @@ class UpdateEquipPacket extends DataPacket{ /** @var int */ public $windowType; /** @var int */ - public $unknownVarint; //TODO: find out what this is (vanilla always sends 0) + public $windowSlotCount; //useless, seems to be part of a standard container header /** @var int */ public $entityUniqueId; /** @var string */ @@ -44,7 +44,7 @@ class UpdateEquipPacket extends DataPacket{ protected function decodePayload(){ $this->windowId = $this->getByte(); $this->windowType = $this->getByte(); - $this->unknownVarint = $this->getVarInt(); + $this->windowSlotCount = $this->getVarInt(); $this->entityUniqueId = $this->getEntityUniqueId(); $this->namedtag = $this->getRemaining(); } @@ -52,7 +52,7 @@ class UpdateEquipPacket extends DataPacket{ protected function encodePayload(){ $this->putByte($this->windowId); $this->putByte($this->windowType); - $this->putVarInt($this->unknownVarint); + $this->putVarInt($this->windowSlotCount); $this->putEntityUniqueId($this->entityUniqueId); $this->put($this->namedtag); } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index 1a0b3be60..ad99f4361 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -38,7 +38,7 @@ class UpdateTradePacket extends DataPacket{ /** @var int */ public $windowType = WindowTypes::TRADING; //Mojang hardcoded this -_- /** @var int */ - public $thisIsAlwaysZero = 0; //hardcoded to 0 + public $windowSlotCount = 0; //useless, seems to be part of a standard container header /** @var int */ public $tradeTier; /** @var int */ @@ -57,7 +57,7 @@ class UpdateTradePacket extends DataPacket{ protected function decodePayload(){ $this->windowId = $this->getByte(); $this->windowType = $this->getByte(); - $this->thisIsAlwaysZero = $this->getVarInt(); + $this->windowSlotCount = $this->getVarInt(); $this->tradeTier = $this->getVarInt(); $this->traderEid = $this->getEntityUniqueId(); $this->playerEid = $this->getEntityUniqueId(); @@ -70,7 +70,7 @@ class UpdateTradePacket extends DataPacket{ protected function encodePayload(){ $this->putByte($this->windowId); $this->putByte($this->windowType); - $this->putVarInt($this->thisIsAlwaysZero); + $this->putVarInt($this->windowSlotCount); $this->putVarInt($this->tradeTier); $this->putEntityUniqueId($this->traderEid); $this->putEntityUniqueId($this->playerEid); diff --git a/src/pocketmine/network/mcpe/protocol/types/PersonaPieceTintColor.php b/src/pocketmine/network/mcpe/protocol/types/PersonaPieceTintColor.php new file mode 100644 index 000000000..05231d3f1 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/PersonaPieceTintColor.php @@ -0,0 +1,55 @@ +pieceType = $pieceType; + $this->colors = $colors; + } + + public function getPieceType() : string{ + return $this->pieceType; + } + + /** + * @return string[] + */ + public function getColors() : array{ + return $this->colors; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/PersonaSkinPiece.php b/src/pocketmine/network/mcpe/protocol/types/PersonaSkinPiece.php new file mode 100644 index 000000000..bb22a1350 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/PersonaSkinPiece.php @@ -0,0 +1,77 @@ +pieceId = $pieceId; + $this->pieceType = $pieceType; + $this->packId = $packId; + $this->isDefaultPiece = $isDefaultPiece; + $this->productId = $productId; + } + + public function getPieceId() : string{ + return $this->pieceId; + } + + public function getPieceType() : string{ + return $this->pieceType; + } + + public function getPackId() : string{ + return $this->packId; + } + + public function isDefaultPiece() : bool{ + return $this->isDefaultPiece; + } + + public function getProductId() : string{ + return $this->productId; + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/types/SkinData.php b/src/pocketmine/network/mcpe/protocol/types/SkinData.php index e7ca29312..1393748b4 100644 --- a/src/pocketmine/network/mcpe/protocol/types/SkinData.php +++ b/src/pocketmine/network/mcpe/protocol/types/SkinData.php @@ -27,6 +27,9 @@ use pocketmine\utils\UUID; class SkinData{ + public const ARM_SIZE_SLIM = "slim"; + public const ARM_SIZE_WIDE = "wide"; + /** @var string */ private $skinId; /** @var string */ @@ -51,11 +54,23 @@ class SkinData{ private $capeId; /** @var string */ private $fullSkinId; + /** @var string */ + private $armSize; + /** @var string */ + private $skinColor; + /** @var PersonaSkinPiece[] */ + private $personaPieces; + /** @var PersonaPieceTintColor[] */ + private $pieceTintColors; + /** @var bool */ + private $isVerified; /** - * @param SkinAnimation[] $animations + * @param SkinAnimation[] $animations + * @param PersonaSkinPiece[] $personaPieces + * @param PersonaPieceTintColor[] $pieceTintColors */ - public function __construct(string $skinId, string $resourcePatch, SkinImage $skinImage, array $animations = [], SkinImage $capeImage = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $personaCapeOnClassic = false, string $capeId = "", ?string $fullSkinId = null){ + public function __construct(string $skinId, string $resourcePatch, SkinImage $skinImage, array $animations = [], SkinImage $capeImage = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $personaCapeOnClassic = false, string $capeId = "", ?string $fullSkinId = null, string $armSize = self::ARM_SIZE_WIDE, string $skinColor = "", array $personaPieces = [], array $pieceTintColors = [], bool $isVerified = false){ $this->skinId = $skinId; $this->resourcePatch = $resourcePatch; $this->skinImage = $skinImage; @@ -69,6 +84,11 @@ class SkinData{ $this->capeId = $capeId; //this has to be unique or the client will do stupid things $this->fullSkinId = $fullSkinId ?? UUID::fromRandom()->toString(); + $this->armSize = $armSize; + $this->skinColor = $skinColor; + $this->personaPieces = $personaPieces; + $this->pieceTintColors = $pieceTintColors; + $this->isVerified = $isVerified; } public function getSkinId() : string{ @@ -121,4 +141,37 @@ class SkinData{ public function getFullSkinId() : string{ return $this->fullSkinId; } + + public function getArmSize() : string{ + return $this->armSize; + } + + public function getSkinColor() : string{ + return $this->skinColor; + } + + /** + * @return PersonaSkinPiece[] + */ + public function getPersonaPieces() : array{ + return $this->personaPieces; + } + + /** + * @return PersonaPieceTintColor[] + */ + public function getPieceTintColors() : array{ + return $this->pieceTintColors; + } + + public function isVerified() : bool{ + return $this->isVerified; + } + + /** + * @internal + */ + public function setVerified(bool $verified) : void{ + $this->isVerified = $verified; + } } diff --git a/src/pocketmine/network/mcpe/protocol/types/StructureEditorData.php b/src/pocketmine/network/mcpe/protocol/types/StructureEditorData.php new file mode 100644 index 000000000..9e7f04263 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/StructureEditorData.php @@ -0,0 +1,48 @@ +