Merge branch 'stable' into next-minor

This commit is contained in:
Dylan K. Taylor
2020-04-18 13:32:52 +01:00
21 changed files with 434 additions and 33 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}

View File

@ -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{

View File

@ -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{

View File

@ -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;

View File

@ -26,16 +26,32 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h>
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{

View File

@ -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);
}

View File

@ -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);

View File

@ -0,0 +1,55 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
final class PersonaPieceTintColor{
public const PIECE_TYPE_PERSONA_EYES = "persona_eyes";
public const PIECE_TYPE_PERSONA_HAIR = "persona_hair";
public const PIECE_TYPE_PERSONA_MOUTH = "persona_mouth";
/** @var string */
private $pieceType;
/** @var string[] */
private $colors;
/**
* @param string[] $colors
*/
public function __construct(string $pieceType, array $colors){
$this->pieceType = $pieceType;
$this->colors = $colors;
}
public function getPieceType() : string{
return $this->pieceType;
}
/**
* @return string[]
*/
public function getColors() : array{
return $this->colors;
}
}

View File

@ -0,0 +1,77 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
final class PersonaSkinPiece{
public const PIECE_TYPE_PERSONA_BODY = "persona_body";
public const PIECE_TYPE_PERSONA_BOTTOM = "persona_bottom";
public const PIECE_TYPE_PERSONA_EYES = "persona_eyes";
public const PIECE_TYPE_PERSONA_FACIAL_HAIR = "persona_facial_hair";
public const PIECE_TYPE_PERSONA_FEET = "persona_feet";
public const PIECE_TYPE_PERSONA_HAIR = "persona_hair";
public const PIECE_TYPE_PERSONA_MOUTH = "persona_mouth";
public const PIECE_TYPE_PERSONA_SKELETON = "persona_skeleton";
public const PIECE_TYPE_PERSONA_SKIN = "persona_skin";
public const PIECE_TYPE_PERSONA_TOP = "persona_top";
/** @var string */
private $pieceId;
/** @var string */
private $pieceType;
/** @var string */
private $packId;
/** @var bool */
private $isDefaultPiece;
/** @var string */
private $productId;
public function __construct(string $pieceId, string $pieceType, string $packId, bool $isDefaultPiece, string $productId){
$this->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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,48 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
class StructureEditorData{
public const TYPE_DATA = 0;
public const TYPE_SAVE = 1;
public const TYPE_LOAD = 2;
public const TYPE_CORNER = 3;
public const TYPE_INVALID = 4;
public const TYPE_EXPORT = 5;
/** @var string */
public $structureName;
/** @var string */
public $structureDataField;
/** @var bool */
public $includePlayers;
/** @var bool */
public $showBoundingBox;
/** @var int */
public $structureBlockType;
/** @var StructureSettings */
public $structureSettings;
/** @var int */
public $structureRedstoneSaveMove;
}

View File

@ -23,6 +23,8 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\math\Vector3;
class StructureSettings{
/** @var string */
public $paletteName;
@ -52,4 +54,6 @@ class StructureSettings{
public $integrityValue;
/** @var int */
public $integritySeed;
/** @var Vector3 */
public $pivot;
}