Merge branch 'stable'

This commit is contained in:
Dylan K. Taylor 2021-03-14 20:14:08 +00:00
commit 3fe0adbd7f
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
24 changed files with 399 additions and 72 deletions

18
changelogs/3.18.md Normal file
View File

@ -0,0 +1,18 @@
**For Minecraft: Bedrock Edition 1.16.210**
### 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.18.0
- Added support for Minecraft: Bedrock Edition 1.16.210.
- Removed compatibility with earlier versions.
## Known issues (please don't open issues for these)
- Walls don't connect to each other
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
- Items can't be removed from item frames in Survival mode

@ -1 +1 @@
Subproject commit 4e58a3c67dea62600ce5fd014b9fd792a50d246d Subproject commit 989e02a6318b1278fda8526dd136749b9b7b34b4

View File

@ -50,6 +50,7 @@ class LegacySkinAdapter implements SkinAdapter{
} }
return new SkinData( return new SkinData(
$skin->getSkinId(), $skin->getSkinId(),
"", //TODO: playfab ID
$resourcePatch, $resourcePatch,
SkinImage::fromLegacy($skin->getSkinData()), [], SkinImage::fromLegacy($skin->getSkinData()), [],
$capeImage, $capeImage,

View File

@ -547,7 +547,7 @@ class InGamePacketHandler extends PacketHandler{
case PlayerActionPacket::ACTION_START_GLIDE: case PlayerActionPacket::ACTION_START_GLIDE:
case PlayerActionPacket::ACTION_STOP_GLIDE: case PlayerActionPacket::ACTION_STOP_GLIDE:
break; //TODO break; //TODO
case PlayerActionPacket::ACTION_CONTINUE_BREAK: case PlayerActionPacket::ACTION_CRACK_BREAK:
$this->player->continueBreakBlock($pos, $packet->face); $this->player->continueBreakBlock($pos, $packet->face);
break; break;
case PlayerActionPacket::ACTION_START_SWIMMING: case PlayerActionPacket::ACTION_START_SWIMMING:

View File

@ -48,6 +48,7 @@ use pocketmine\network\mcpe\protocol\CameraPacket;
use pocketmine\network\mcpe\protocol\CameraShakePacket; use pocketmine\network\mcpe\protocol\CameraShakePacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundDebugRendererPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket; use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket;
use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket; use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket;
@ -826,4 +827,8 @@ abstract class PacketHandler implements PacketHandlerInterface{
public function handleFilterText(FilterTextPacket $packet) : bool{ public function handleFilterText(FilterTextPacket $packet) : bool{
return false; return false;
} }
public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool{
return false;
}
} }

View File

@ -33,6 +33,8 @@ use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\BoolGameRule;
use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\Experiments; use pocketmine\network\mcpe\protocol\types\Experiments;
use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings;
use pocketmine\network\mcpe\protocol\types\PlayerMovementType;
use pocketmine\network\mcpe\protocol\types\SpawnSettings; use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\Server; use pocketmine\Server;
@ -86,6 +88,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$pk->levelId = ""; $pk->levelId = "";
$pk->worldName = $this->server->getMotd(); $pk->worldName = $this->server->getMotd();
$pk->itemTable = ItemTypeDictionary::getInstance()->getEntries(); //TODO: check if this is actually needed $pk->itemTable = ItemTypeDictionary::getInstance()->getEntries(); //TODO: check if this is actually needed
$pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false);
$this->session->sendDataPacket($pk); $this->session->sendDataPacket($pk);
$this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers());

View File

@ -54,13 +54,15 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S
public const FLYING = 0x200; public const FLYING = 0x200;
public const MUTED = 0x400; public const MUTED = 0x400;
public const BUILD_AND_MINE = 0x01 | self::BITFLAG_SECOND_SET; public const MINE = 0x01 | self::BITFLAG_SECOND_SET;
public const DOORS_AND_SWITCHES = 0x02 | self::BITFLAG_SECOND_SET; public const DOORS_AND_SWITCHES = 0x02 | self::BITFLAG_SECOND_SET;
public const OPEN_CONTAINERS = 0x04 | self::BITFLAG_SECOND_SET; public const OPEN_CONTAINERS = 0x04 | self::BITFLAG_SECOND_SET;
public const ATTACK_PLAYERS = 0x08 | self::BITFLAG_SECOND_SET; public const ATTACK_PLAYERS = 0x08 | self::BITFLAG_SECOND_SET;
public const ATTACK_MOBS = 0x10 | self::BITFLAG_SECOND_SET; public const ATTACK_MOBS = 0x10 | self::BITFLAG_SECOND_SET;
public const OPERATOR = 0x20 | self::BITFLAG_SECOND_SET; public const OPERATOR = 0x20 | self::BITFLAG_SECOND_SET;
public const TELEPORT = 0x80 | self::BITFLAG_SECOND_SET; public const TELEPORT = 0x80 | self::BITFLAG_SECOND_SET;
public const BUILD = 0x100 | self::BITFLAG_SECOND_SET;
public const DEFAULT = 0x200 | self::BITFLAG_SECOND_SET;
/** @var int */ /** @var int */
public $flags = 0; public $flags = 0;

View File

@ -33,18 +33,24 @@ class CameraShakePacket extends DataPacket implements ClientboundPacket{
public const TYPE_POSITIONAL = 0; public const TYPE_POSITIONAL = 0;
public const TYPE_ROTATIONAL = 1; public const TYPE_ROTATIONAL = 1;
public const ACTION_ADD = 0;
public const ACTION_STOP = 1;
/** @var float */ /** @var float */
private $intensity; private $intensity;
/** @var float */ /** @var float */
private $duration; private $duration;
/** @var int */ /** @var int */
private $shakeType; private $shakeType;
/** @var int */
private $shakeAction;
public static function create(float $intensity, float $duration, int $shakeType) : self{ public static function create(float $intensity, float $duration, int $shakeType, int $shakeAction) : self{
$result = new self; $result = new self;
$result->intensity = $intensity; $result->intensity = $intensity;
$result->duration = $duration; $result->duration = $duration;
$result->shakeType = $shakeType; $result->shakeType = $shakeType;
$result->shakeAction = $shakeAction;
return $result; return $result;
} }
@ -54,16 +60,20 @@ class CameraShakePacket extends DataPacket implements ClientboundPacket{
public function getShakeType() : int{ return $this->shakeType; } public function getShakeType() : int{ return $this->shakeType; }
public function getShakeAction() : int{ return $this->shakeAction; }
protected function decodePayload(PacketSerializer $in) : void{ protected function decodePayload(PacketSerializer $in) : void{
$this->intensity = $in->getLFloat(); $this->intensity = $in->getLFloat();
$this->duration = $in->getLFloat(); $this->duration = $in->getLFloat();
$this->shakeType = $in->getByte(); $this->shakeType = $in->getByte();
$this->shakeAction = $in->getByte();
} }
protected function encodePayload(PacketSerializer $out) : void{ protected function encodePayload(PacketSerializer $out) : void{
$out->putLFloat($this->intensity); $out->putLFloat($this->intensity);
$out->putLFloat($this->duration); $out->putLFloat($this->duration);
$out->putByte($this->shakeType); $out->putByte($this->shakeType);
$out->putByte($this->shakeAction);
} }
public function handle(PacketHandlerInterface $handler) : bool{ public function handle(PacketHandlerInterface $handler) : bool{

View File

@ -0,0 +1,137 @@
<?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;
#include <rules/DataPacket.h>
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
class ClientboundDebugRendererPacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_DEBUG_RENDERER_PACKET;
public const TYPE_CLEAR = 1;
public const TYPE_ADD_CUBE = 2;
/** @var int */
private $type;
//TODO: if more types are added, we'll probably want to make a separate data type and interfaces
/** @var string */
private $text;
/** @var Vector3 */
private $position;
/** @var float */
private $red;
/** @var float */
private $green;
/** @var float */
private $blue;
/** @var float */
private $alpha;
/** @var int */
private $durationMillis;
private static function base(int $type) : self{
$result = new self;
$result->type = $type;
return $result;
}
public static function clear() : self{ return self::base(self::TYPE_CLEAR); }
public static function addCube(string $text, Vector3 $position, float $red, float $green, float $blue, float $alpha, int $durationMillis) : self{
$result = self::base(self::TYPE_ADD_CUBE);
$result->text = $text;
$result->position = $position;
$result->red = $red;
$result->green = $green;
$result->blue = $blue;
$result->alpha = $alpha;
$result->durationMillis = $durationMillis;
return $result;
}
public function getType() : int{ return $this->type; }
public function getText() : string{ return $this->text; }
public function getPosition() : Vector3{ return $this->position; }
public function getRed() : float{ return $this->red; }
public function getGreen() : float{ return $this->green; }
public function getBlue() : float{ return $this->blue; }
public function getAlpha() : float{ return $this->alpha; }
public function getDurationMillis() : int{ return $this->durationMillis; }
protected function decodePayload(PacketSerializer $in) : void{
$this->type = $in->getLInt();
switch($this->type){
case self::TYPE_CLEAR:
//NOOP
break;
case self::TYPE_ADD_CUBE:
$this->text = $in->getString();
$this->position = $in->getVector3();
$this->red = $in->getLFloat();
$this->green = $in->getLFloat();
$this->blue = $in->getLFloat();
$this->alpha = $in->getLFloat();
$this->durationMillis = $in->getLLong();
break;
default:
throw new \UnexpectedValueException("Unknown type " . $this->type);
}
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putLInt($this->type);
switch($this->type){
case self::TYPE_CLEAR:
//NOOP
break;
case self::TYPE_ADD_CUBE:
$out->putString($this->text);
$out->putVector3($this->position);
$out->putLFloat($this->red);
$out->putLFloat($this->green);
$out->putLFloat($this->blue);
$out->putLFloat($this->alpha);
$out->putLLong($this->durationMillis);
break;
default:
throw new \InvalidArgumentException("Unknown type " . $this->type);
}
}
public function handle(PacketHandlerInterface $handler) : bool{
return $handler->handleClientboundDebugRenderer($this);
}
}

View File

@ -342,4 +342,6 @@ interface PacketHandlerInterface{
public function handleItemComponent(ItemComponentPacket $packet) : bool; public function handleItemComponent(ItemComponentPacket $packet) : bool;
public function handleFilterText(FilterTextPacket $packet) : bool; public function handleFilterText(FilterTextPacket $packet) : bool;
public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool;
} }

View File

@ -201,6 +201,7 @@ class PacketPool{
$this->registerPacket(new CorrectPlayerMovePredictionPacket()); $this->registerPacket(new CorrectPlayerMovePredictionPacket());
$this->registerPacket(new ItemComponentPacket()); $this->registerPacket(new ItemComponentPacket());
$this->registerPacket(new FilterTextPacket()); $this->registerPacket(new FilterTextPacket());
$this->registerPacket(new ClientboundDebugRendererPacket());
} }
public function registerPacket(Packet $packet) : void{ public function registerPacket(Packet $packet) : void{

View File

@ -48,7 +48,7 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{
public const ACTION_START_GLIDE = 15; public const ACTION_START_GLIDE = 15;
public const ACTION_STOP_GLIDE = 16; public const ACTION_STOP_GLIDE = 16;
public const ACTION_BUILD_DENIED = 17; public const ACTION_BUILD_DENIED = 17;
public const ACTION_CONTINUE_BREAK = 18; public const ACTION_CRACK_BREAK = 18;
public const ACTION_CHANGE_SKIN = 19; public const ACTION_CHANGE_SKIN = 19;
public const ACTION_SET_ENCHANTMENT_SEED = 20; //no longer used public const ACTION_SET_ENCHANTMENT_SEED = 20; //no longer used
public const ACTION_START_SWIMMING = 21; public const ACTION_START_SWIMMING = 21;
@ -56,6 +56,8 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{
public const ACTION_START_SPIN_ATTACK = 23; public const ACTION_START_SPIN_ATTACK = 23;
public const ACTION_STOP_SPIN_ATTACK = 24; public const ACTION_STOP_SPIN_ATTACK = 24;
public const ACTION_INTERACT_BLOCK = 25; public const ACTION_INTERACT_BLOCK = 25;
public const ACTION_PREDICT_DESTROY_BLOCK = 26;
public const ACTION_CONTINUE_DESTROY_BLOCK = 27;
/** @var int */ /** @var int */
public $entityRuntimeId; public $entityRuntimeId;

View File

@ -41,11 +41,11 @@ final class ProtocolInfo{
*/ */
/** Actual Minecraft: PE protocol version */ /** Actual Minecraft: PE protocol version */
public const CURRENT_PROTOCOL = 422; public const CURRENT_PROTOCOL = 428;
/** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */
public const MINECRAFT_VERSION = 'v1.16.200'; public const MINECRAFT_VERSION = 'v1.16.210';
/** Version number sent to clients in ping responses. */ /** Version number sent to clients in ping responses. */
public const MINECRAFT_VERSION_NETWORK = '1.16.200'; public const MINECRAFT_VERSION_NETWORK = '1.16.210';
public const LOGIN_PACKET = 0x01; public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02; public const PLAY_STATUS_PACKET = 0x02;
@ -210,5 +210,6 @@ final class ProtocolInfo{
public const CORRECT_PLAYER_MOVE_PREDICTION_PACKET = 0xa1; public const CORRECT_PLAYER_MOVE_PREDICTION_PACKET = 0xa1;
public const ITEM_COMPONENT_PACKET = 0xa2; public const ITEM_COMPONENT_PACKET = 0xa2;
public const FILTER_TEXT_PACKET = 0xa3; public const FILTER_TEXT_PACKET = 0xa3;
public const CLIENTBOUND_DEBUG_RENDERER_PACKET = 0xa4;
} }

View File

@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\types\GameRule;
use pocketmine\network\mcpe\protocol\types\GeneratorType; use pocketmine\network\mcpe\protocol\types\GeneratorType;
use pocketmine\network\mcpe\protocol\types\ItemTypeEntry; use pocketmine\network\mcpe\protocol\types\ItemTypeEntry;
use pocketmine\network\mcpe\protocol\types\MultiplayerGameVisibility; use pocketmine\network\mcpe\protocol\types\MultiplayerGameVisibility;
use pocketmine\network\mcpe\protocol\types\PlayerMovementType; use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\SpawnSettings; use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use function count; use function count;
@ -153,8 +153,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $premiumWorldTemplateId = ""; public $premiumWorldTemplateId = "";
/** @var bool */ /** @var bool */
public $isTrial = false; public $isTrial = false;
/** @var int */ /** @var PlayerMovementSettings */
public $playerMovementType = PlayerMovementType::LEGACY; public $playerMovementSettings;
/** @var int */ /** @var int */
public $currentTick = 0; //only used if isTrial is true public $currentTick = 0; //only used if isTrial is true
/** @var int */ /** @var int */
@ -233,7 +233,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->worldName = $in->getString(); $this->worldName = $in->getString();
$this->premiumWorldTemplateId = $in->getString(); $this->premiumWorldTemplateId = $in->getString();
$this->isTrial = $in->getBool(); $this->isTrial = $in->getBool();
$this->playerMovementType = $in->getVarInt(); $this->playerMovementSettings = PlayerMovementSettings::read($in);
$this->currentTick = $in->getLLong(); $this->currentTick = $in->getLLong();
$this->enchantmentSeed = $in->getVarInt(); $this->enchantmentSeed = $in->getVarInt();
@ -315,7 +315,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$out->putString($this->worldName); $out->putString($this->worldName);
$out->putString($this->premiumWorldTemplateId); $out->putString($this->premiumWorldTemplateId);
$out->putBool($this->isTrial); $out->putBool($this->isTrial);
$out->putVarInt($this->playerMovementType); $this->playerMovementSettings->write($out);
$out->putLLong($this->currentTick); $out->putLLong($this->currentTick);
$out->putVarInt($this->enchantmentSeed); $out->putVarInt($this->enchantmentSeed);

View File

@ -100,6 +100,7 @@ class PacketSerializer extends BinaryStream{
public function getSkin() : SkinData{ public function getSkin() : SkinData{
$skinId = $this->getString(); $skinId = $this->getString();
$skinPlayFabId = $this->getString();
$skinResourcePatch = $this->getString(); $skinResourcePatch = $this->getString();
$skinData = $this->getSkinImage(); $skinData = $this->getSkinImage();
$animationCount = $this->getLInt(); $animationCount = $this->getLInt();
@ -146,11 +147,12 @@ class PacketSerializer extends BinaryStream{
); );
} }
return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId, $armSize, $skinColor, $personaPieces, $pieceTintColors); return new SkinData($skinId, $skinPlayFabId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId, $armSize, $skinColor, $personaPieces, $pieceTintColors);
} }
public function putSkin(SkinData $skin) : void{ public function putSkin(SkinData $skin) : void{
$this->putString($skin->getSkinId()); $this->putString($skin->getSkinId());
$this->putString($skin->getPlayFabId());
$this->putString($skin->getResourcePatch()); $this->putString($skin->getResourcePatch());
$this->putSkinImage($skin->getSkinImage()); $this->putSkinImage($skin->getSkinImage());
$this->putLInt(count($skin->getAnimations())); $this->putLInt(count($skin->getAnimations()));

View File

@ -0,0 +1,61 @@
<?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;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class PlayerMovementSettings{
/** @var int */
private $movementType;
/** @var int */
private $rewindHistorySize;
/** @var bool */
private $serverAuthoritativeBlockBreaking;
public function __construct(int $movementType, int $rewindHistorySize, bool $serverAuthoritativeBlockBreaking){
$this->movementType = $movementType;
$this->rewindHistorySize = $rewindHistorySize;
//do not ask me what the F this is doing here
$this->serverAuthoritativeBlockBreaking = $serverAuthoritativeBlockBreaking;
}
public function getMovementType() : int{ return $this->movementType; }
public function getRewindHistorySize() : int{ return $this->rewindHistorySize; }
public function isServerAuthoritativeBlockBreaking() : bool{ return $this->serverAuthoritativeBlockBreaking; }
public static function read(PacketSerializer $in) : self{
$movementType = $in->getVarInt();
$rewindHistorySize = $in->getVarInt();
$serverAuthBlockBreaking = $in->getBool();
return new self($movementType, $rewindHistorySize, $serverAuthBlockBreaking);
}
public function write(PacketSerializer $out) : void{
$out->putVarInt($this->movementType);
$out->putVarInt($this->rewindHistorySize);
$out->putBool($this->serverAuthoritativeBlockBreaking);
}
}

View File

@ -96,54 +96,55 @@ final class EntityMetadataProperties{
public const RIDER_ROTATION_LOCKED = 57; //byte public const RIDER_ROTATION_LOCKED = 57; //byte
public const RIDER_MAX_ROTATION = 58; //float public const RIDER_MAX_ROTATION = 58; //float
public const RIDER_MIN_ROTATION = 59; //float public const RIDER_MIN_ROTATION = 59; //float
public const AREA_EFFECT_CLOUD_RADIUS = 60; //float public const RIDER_SEAT_ROTATION_OFFSET = 60; //TODO: find type
public const AREA_EFFECT_CLOUD_WAITING = 61; //int public const AREA_EFFECT_CLOUD_RADIUS = 61; //float
public const AREA_EFFECT_CLOUD_PARTICLE_ID = 62; //int public const AREA_EFFECT_CLOUD_WAITING = 62; //int
/* 63 (int) shulker-related */ public const AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int
public const SHULKER_ATTACH_FACE = 64; //byte /* 64 (int) shulker-related */
/* 65 (short) shulker-related */ public const SHULKER_ATTACH_FACE = 65; //byte
public const SHULKER_ATTACH_POS = 66; //block coords /* 66 (short) shulker-related */
public const TRADING_PLAYER_EID = 67; //long public const SHULKER_ATTACH_POS = 67; //block coords
public const TRADING_PLAYER_EID = 68; //long
/* 69 (byte) command-block */ /* 70 (byte) command-block */
public const COMMAND_BLOCK_COMMAND = 70; //string public const COMMAND_BLOCK_COMMAND = 71; //string
public const COMMAND_BLOCK_LAST_OUTPUT = 71; //string public const COMMAND_BLOCK_LAST_OUTPUT = 72; //string
public const COMMAND_BLOCK_TRACK_OUTPUT = 72; //byte public const COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte
public const CONTROLLING_RIDER_SEAT_NUMBER = 73; //byte public const CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte
public const STRENGTH = 74; //int public const STRENGTH = 75; //int
public const MAX_STRENGTH = 75; //int public const MAX_STRENGTH = 76; //int
/* 76 (int) */ /* 77 (int) */
public const LIMITED_LIFE = 77; public const LIMITED_LIFE = 78;
public const ARMOR_STAND_POSE_INDEX = 78; //int public const ARMOR_STAND_POSE_INDEX = 79; //int
public const ENDER_CRYSTAL_TIME_OFFSET = 79; //int public const ENDER_CRYSTAL_TIME_OFFSET = 80; //int
public const ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always public const ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always
public const COLOR_2 = 81; //byte public const COLOR_2 = 82; //byte
/* 82 (unknown) */ /* 83 (unknown) */
public const SCORE_TAG = 83; //string public const SCORE_TAG = 84; //string
public const BALLOON_ATTACHED_ENTITY = 84; //int64, entity unique ID of owner public const BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner
public const PUFFERFISH_SIZE = 85; //byte public const PUFFERFISH_SIZE = 86; //byte
public const BOAT_BUBBLE_TIME = 86; //int (time in bubble column) public const BOAT_BUBBLE_TIME = 87; //int (time in bubble column)
public const PLAYER_AGENT_EID = 87; //long public const PLAYER_AGENT_EID = 88; //long
/* 88 (float) related to panda sitting /* 89 (float) related to panda sitting
* 89 (float) related to panda sitting */ * 90 (float) related to panda sitting */
public const EAT_COUNTER = 90; //int (used by pandas) public const EAT_COUNTER = 91; //int (used by pandas)
public const FLAGS2 = 91; //long (extended data flags) public const FLAGS2 = 92; //long (extended data flags)
/* 92 (float) related to panda lying down /* 93 (float) related to panda lying down
* 93 (float) related to panda lying down */ * 94 (float) related to panda lying down */
public const AREA_EFFECT_CLOUD_DURATION = 94; //int public const AREA_EFFECT_CLOUD_DURATION = 95; //int
public const AREA_EFFECT_CLOUD_SPAWN_TIME = 95; //int public const AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int
public const AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 96; //float, usually negative public const AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative
public const AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 97; //float public const AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float
public const AREA_EFFECT_CLOUD_PICKUP_COUNT = 98; //int public const AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int
public const INTERACTIVE_TAG = 99; //string (button text) public const INTERACTIVE_TAG = 100; //string (button text)
public const TRADE_TIER = 100; //int public const TRADE_TIER = 101; //int
public const MAX_TRADE_TIER = 101; //int public const MAX_TRADE_TIER = 102; //int
public const TRADE_XP = 102; //int public const TRADE_XP = 103; //int
public const SKIN_ID = 103; //int ??? public const SKIN_ID = 104; //int ???
/* 104 (int) related to wither */ /* 105 (int) related to wither */
public const COMMAND_BLOCK_TICK_DELAY = 105; //int public const COMMAND_BLOCK_TICK_DELAY = 106; //int
public const COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 106; //byte public const COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 107; //byte
public const AMBIENT_SOUND_INTERVAL_MIN = 107; //float public const AMBIENT_SOUND_INTERVAL_MIN = 108; //float
public const AMBIENT_SOUND_INTERVAL_RANGE = 108; //float public const AMBIENT_SOUND_INTERVAL_RANGE = 109; //float
public const AMBIENT_SOUND_EVENT = 109; //string public const AMBIENT_SOUND_EVENT = 110; //string
} }

View File

@ -70,6 +70,7 @@ final class ItemStackRequest{
case CraftingMarkSecondaryResultStackRequestAction::getTypeId(): return CraftingMarkSecondaryResultStackRequestAction::read($in); case CraftingMarkSecondaryResultStackRequestAction::getTypeId(): return CraftingMarkSecondaryResultStackRequestAction::read($in);
case LabTableCombineStackRequestAction::getTypeId(): return LabTableCombineStackRequestAction::read($in); case LabTableCombineStackRequestAction::getTypeId(): return LabTableCombineStackRequestAction::read($in);
case BeaconPaymentStackRequestAction::getTypeId(): return BeaconPaymentStackRequestAction::read($in); case BeaconPaymentStackRequestAction::getTypeId(): return BeaconPaymentStackRequestAction::read($in);
case MineBlockStackRequestAction::getTypeId(): return MineBlockStackRequestAction::read($in);
case CraftRecipeStackRequestAction::getTypeId(): return CraftRecipeStackRequestAction::read($in); case CraftRecipeStackRequestAction::getTypeId(): return CraftRecipeStackRequestAction::read($in);
case CraftRecipeAutoStackRequestAction::getTypeId(): return CraftRecipeAutoStackRequestAction::read($in); case CraftRecipeAutoStackRequestAction::getTypeId(): return CraftRecipeAutoStackRequestAction::read($in);
case CreativeCreateStackRequestAction::getTypeId(): return CreativeCreateStackRequestAction::read($in); case CreativeCreateStackRequestAction::getTypeId(): return CreativeCreateStackRequestAction::read($in);

View File

@ -38,10 +38,11 @@ final class ItemStackRequestActionType{
public const CRAFTING_MARK_SECONDARY_RESULT_SLOT = 6; public const CRAFTING_MARK_SECONDARY_RESULT_SLOT = 6;
public const LAB_TABLE_COMBINE = 7; public const LAB_TABLE_COMBINE = 7;
public const BEACON_PAYMENT = 8; public const BEACON_PAYMENT = 8;
public const CRAFTING_RECIPE = 9; public const MINE_BLOCK = 9;
public const CRAFTING_RECIPE_AUTO = 10; //recipe book? public const CRAFTING_RECIPE = 10;
public const CREATIVE_CREATE = 11; public const CRAFTING_RECIPE_AUTO = 11; //recipe book?
public const CRAFTING_RECIPE_OPTIONAL = 12; //anvil/cartography table rename public const CREATIVE_CREATE = 12;
public const CRAFTING_NON_IMPLEMENTED_DEPRECATED_ASK_TY_LAING = 13; public const CRAFTING_RECIPE_OPTIONAL = 13; //anvil/cartography table rename
public const CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING = 14; //no idea what this is for public const CRAFTING_NON_IMPLEMENTED_DEPRECATED_ASK_TY_LAING = 14;
public const CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING = 15; //no idea what this is for
} }

View File

@ -0,0 +1,63 @@
<?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\inventory\stackrequest;
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
final class MineBlockStackRequestAction extends ItemStackRequestAction{
/** @var int */
private $unknown1;
/** @var int */
private $predictedDurability;
/** @var int */
private $stackId;
public function __construct(int $unknown1, int $predictedDurability, int $stackId){
$this->unknown1 = $unknown1;
$this->predictedDurability = $predictedDurability;
$this->stackId = $stackId;
}
public function getUnknown1() : int{ return $this->unknown1; }
public function getPredictedDurability() : int{ return $this->predictedDurability; }
public function getStackId() : int{ return $this->stackId; }
public static function getTypeId() : int{ return ItemStackRequestActionType::MINE_BLOCK; }
public static function read(PacketSerializer $in) : self{
$unknown1 = $in->getVarInt();
$predictedDurability = $in->getVarInt();
$stackId = $in->readGenericTypeNetworkId();
return new self($unknown1, $predictedDurability, $stackId);
}
public function write(PacketSerializer $out) : void{
$out->putVarInt($this->unknown1);
$out->putVarInt($this->predictedDurability);
$out->writeGenericTypeNetworkId($this->stackId);
}
}

View File

@ -37,13 +37,16 @@ final class ItemStackResponseSlotInfo{
private $itemStackId; private $itemStackId;
/** @var string */ /** @var string */
private $customName; private $customName;
/** @var int */
private $durabilityCorrection;
public function __construct(int $slot, int $hotbarSlot, int $count, int $itemStackId, string $customName){ public function __construct(int $slot, int $hotbarSlot, int $count, int $itemStackId, string $customName, int $durabilityCorrection){
$this->slot = $slot; $this->slot = $slot;
$this->hotbarSlot = $hotbarSlot; $this->hotbarSlot = $hotbarSlot;
$this->count = $count; $this->count = $count;
$this->itemStackId = $itemStackId; $this->itemStackId = $itemStackId;
$this->customName = $customName; $this->customName = $customName;
$this->durabilityCorrection = $durabilityCorrection;
} }
public function getSlot() : int{ return $this->slot; } public function getSlot() : int{ return $this->slot; }
@ -56,13 +59,16 @@ final class ItemStackResponseSlotInfo{
public function getCustomName() : string{ return $this->customName; } public function getCustomName() : string{ return $this->customName; }
public function getDurabilityCorrection() : int{ return $this->durabilityCorrection; }
public static function read(PacketSerializer $in) : self{ public static function read(PacketSerializer $in) : self{
$slot = $in->getByte(); $slot = $in->getByte();
$hotbarSlot = $in->getByte(); $hotbarSlot = $in->getByte();
$count = $in->getByte(); $count = $in->getByte();
$itemStackId = $in->readGenericTypeNetworkId(); $itemStackId = $in->readGenericTypeNetworkId();
$customName = $in->getString(); $customName = $in->getString();
return new self($slot, $hotbarSlot, $count, $itemStackId, $customName); $durabilityCorrection = $in->getVarInt();
return new self($slot, $hotbarSlot, $count, $itemStackId, $customName, $durabilityCorrection);
} }
public function write(PacketSerializer $out) : void{ public function write(PacketSerializer $out) : void{
@ -71,5 +77,6 @@ final class ItemStackResponseSlotInfo{
$out->putByte($this->count); $out->putByte($this->count);
$out->writeGenericTypeNetworkId($this->itemStackId); $out->writeGenericTypeNetworkId($this->itemStackId);
$out->putString($this->customName); $out->putString($this->customName);
$out->putVarInt($this->durabilityCorrection);
} }
} }

View File

@ -102,6 +102,9 @@ final class ClientData{
public string $PlatformUserId = ""; //xbox-only, apparently public string $PlatformUserId = ""; //xbox-only, apparently
/** @required */
public string $PlayFabId;
/** @required */ /** @required */
public bool $PremiumSkin = false; public bool $PremiumSkin = false;

View File

@ -66,6 +66,7 @@ final class ClientDataToSkinDataHelper{
} }
return new SkinData( return new SkinData(
$clientData->SkinId, $clientData->SkinId,
$clientData->PlayFabId,
self::safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), self::safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"),
new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, self::safeB64Decode($clientData->SkinData, "SkinData")), new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, self::safeB64Decode($clientData->SkinData, "SkinData")),
$animations, $animations,

View File

@ -33,6 +33,8 @@ class SkinData{
/** @var string */ /** @var string */
private $skinId; private $skinId;
/** @var string */ /** @var string */
private $playFabId;
/** @var string */
private $resourcePatch; private $resourcePatch;
/** @var SkinImage */ /** @var SkinImage */
private $skinImage; private $skinImage;
@ -70,8 +72,9 @@ class SkinData{
* @param PersonaSkinPiece[] $personaPieces * @param PersonaSkinPiece[] $personaPieces
* @param PersonaPieceTintColor[] $pieceTintColors * @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, string $armSize = self::ARM_SIZE_WIDE, string $skinColor = "", array $personaPieces = [], array $pieceTintColors = [], bool $isVerified = true){ public function __construct(string $skinId, string $playFabId, 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 = true){
$this->skinId = $skinId; $this->skinId = $skinId;
$this->playFabId = $playFabId;
$this->resourcePatch = $resourcePatch; $this->resourcePatch = $resourcePatch;
$this->skinImage = $skinImage; $this->skinImage = $skinImage;
$this->animations = $animations; $this->animations = $animations;
@ -95,6 +98,8 @@ class SkinData{
return $this->skinId; return $this->skinId;
} }
public function getPlayFabId() : string{ return $this->playFabId; }
public function getResourcePatch() : string{ public function getResourcePatch() : string{
return $this->resourcePatch; return $this->resourcePatch;
} }