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(
$skin->getSkinId(),
"", //TODO: playfab ID
$resourcePatch,
SkinImage::fromLegacy($skin->getSkinData()), [],
$capeImage,

View File

@ -547,7 +547,7 @@ class InGamePacketHandler extends PacketHandler{
case PlayerActionPacket::ACTION_START_GLIDE:
case PlayerActionPacket::ACTION_STOP_GLIDE:
break; //TODO
case PlayerActionPacket::ACTION_CONTINUE_BREAK:
case PlayerActionPacket::ACTION_CRACK_BREAK:
$this->player->continueBreakBlock($pos, $packet->face);
break;
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\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundDebugRendererPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket;
use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket;
@ -826,4 +827,8 @@ abstract class PacketHandler implements PacketHandlerInterface{
public function handleFilterText(FilterTextPacket $packet) : bool{
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\DimensionIds;
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\player\Player;
use pocketmine\Server;
@ -86,6 +88,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$pk->levelId = "";
$pk->worldName = $this->server->getMotd();
$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(StaticPacketCache::getInstance()->getAvailableActorIdentifiers());

View File

@ -54,13 +54,15 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S
public const FLYING = 0x200;
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 OPEN_CONTAINERS = 0x04 | self::BITFLAG_SECOND_SET;
public const ATTACK_PLAYERS = 0x08 | self::BITFLAG_SECOND_SET;
public const ATTACK_MOBS = 0x10 | self::BITFLAG_SECOND_SET;
public const OPERATOR = 0x20 | 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 */
public $flags = 0;

View File

@ -33,18 +33,24 @@ class CameraShakePacket extends DataPacket implements ClientboundPacket{
public const TYPE_POSITIONAL = 0;
public const TYPE_ROTATIONAL = 1;
public const ACTION_ADD = 0;
public const ACTION_STOP = 1;
/** @var float */
private $intensity;
/** @var float */
private $duration;
/** @var int */
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->intensity = $intensity;
$result->duration = $duration;
$result->shakeType = $shakeType;
$result->shakeAction = $shakeAction;
return $result;
}
@ -54,16 +60,20 @@ class CameraShakePacket extends DataPacket implements ClientboundPacket{
public function getShakeType() : int{ return $this->shakeType; }
public function getShakeAction() : int{ return $this->shakeAction; }
protected function decodePayload(PacketSerializer $in) : void{
$this->intensity = $in->getLFloat();
$this->duration = $in->getLFloat();
$this->shakeType = $in->getByte();
$this->shakeAction = $in->getByte();
}
protected function encodePayload(PacketSerializer $out) : void{
$out->putLFloat($this->intensity);
$out->putLFloat($this->duration);
$out->putByte($this->shakeType);
$out->putByte($this->shakeAction);
}
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 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 ItemComponentPacket());
$this->registerPacket(new FilterTextPacket());
$this->registerPacket(new ClientboundDebugRendererPacket());
}
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_STOP_GLIDE = 16;
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_SET_ENCHANTMENT_SEED = 20; //no longer used
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_STOP_SPIN_ATTACK = 24;
public const ACTION_INTERACT_BLOCK = 25;
public const ACTION_PREDICT_DESTROY_BLOCK = 26;
public const ACTION_CONTINUE_DESTROY_BLOCK = 27;
/** @var int */
public $entityRuntimeId;

View File

@ -41,11 +41,11 @@ final class ProtocolInfo{
*/
/** 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. */
public const MINECRAFT_VERSION = 'v1.16.200';
public const MINECRAFT_VERSION = 'v1.16.210';
/** 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 PLAY_STATUS_PACKET = 0x02;
@ -210,5 +210,6 @@ final class ProtocolInfo{
public const CORRECT_PLAYER_MOVE_PREDICTION_PACKET = 0xa1;
public const ITEM_COMPONENT_PACKET = 0xa2;
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\ItemTypeEntry;
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\SpawnSettings;
use function count;
@ -153,8 +153,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
public $premiumWorldTemplateId = "";
/** @var bool */
public $isTrial = false;
/** @var int */
public $playerMovementType = PlayerMovementType::LEGACY;
/** @var PlayerMovementSettings */
public $playerMovementSettings;
/** @var int */
public $currentTick = 0; //only used if isTrial is true
/** @var int */
@ -233,7 +233,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$this->worldName = $in->getString();
$this->premiumWorldTemplateId = $in->getString();
$this->isTrial = $in->getBool();
$this->playerMovementType = $in->getVarInt();
$this->playerMovementSettings = PlayerMovementSettings::read($in);
$this->currentTick = $in->getLLong();
$this->enchantmentSeed = $in->getVarInt();
@ -315,7 +315,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
$out->putString($this->worldName);
$out->putString($this->premiumWorldTemplateId);
$out->putBool($this->isTrial);
$out->putVarInt($this->playerMovementType);
$this->playerMovementSettings->write($out);
$out->putLLong($this->currentTick);
$out->putVarInt($this->enchantmentSeed);

View File

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

View File

@ -70,6 +70,7 @@ final class ItemStackRequest{
case CraftingMarkSecondaryResultStackRequestAction::getTypeId(): return CraftingMarkSecondaryResultStackRequestAction::read($in);
case LabTableCombineStackRequestAction::getTypeId(): return LabTableCombineStackRequestAction::read($in);
case BeaconPaymentStackRequestAction::getTypeId(): return BeaconPaymentStackRequestAction::read($in);
case MineBlockStackRequestAction::getTypeId(): return MineBlockStackRequestAction::read($in);
case CraftRecipeStackRequestAction::getTypeId(): return CraftRecipeStackRequestAction::read($in);
case CraftRecipeAutoStackRequestAction::getTypeId(): return CraftRecipeAutoStackRequestAction::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 LAB_TABLE_COMBINE = 7;
public const BEACON_PAYMENT = 8;
public const CRAFTING_RECIPE = 9;
public const CRAFTING_RECIPE_AUTO = 10; //recipe book?
public const CREATIVE_CREATE = 11;
public const CRAFTING_RECIPE_OPTIONAL = 12; //anvil/cartography table rename
public const CRAFTING_NON_IMPLEMENTED_DEPRECATED_ASK_TY_LAING = 13;
public const CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING = 14; //no idea what this is for
public const MINE_BLOCK = 9;
public const CRAFTING_RECIPE = 10;
public const CRAFTING_RECIPE_AUTO = 11; //recipe book?
public const CREATIVE_CREATE = 12;
public const CRAFTING_RECIPE_OPTIONAL = 13; //anvil/cartography table rename
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;
/** @var string */
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->hotbarSlot = $hotbarSlot;
$this->count = $count;
$this->itemStackId = $itemStackId;
$this->customName = $customName;
$this->durabilityCorrection = $durabilityCorrection;
}
public function getSlot() : int{ return $this->slot; }
@ -56,13 +59,16 @@ final class ItemStackResponseSlotInfo{
public function getCustomName() : string{ return $this->customName; }
public function getDurabilityCorrection() : int{ return $this->durabilityCorrection; }
public static function read(PacketSerializer $in) : self{
$slot = $in->getByte();
$hotbarSlot = $in->getByte();
$count = $in->getByte();
$itemStackId = $in->readGenericTypeNetworkId();
$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{
@ -71,5 +77,6 @@ final class ItemStackResponseSlotInfo{
$out->putByte($this->count);
$out->writeGenericTypeNetworkId($this->itemStackId);
$out->putString($this->customName);
$out->putVarInt($this->durabilityCorrection);
}
}

View File

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

View File

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

View File

@ -33,6 +33,8 @@ class SkinData{
/** @var string */
private $skinId;
/** @var string */
private $playFabId;
/** @var string */
private $resourcePatch;
/** @var SkinImage */
private $skinImage;
@ -70,8 +72,9 @@ class SkinData{
* @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, 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->playFabId = $playFabId;
$this->resourcePatch = $resourcePatch;
$this->skinImage = $skinImage;
$this->animations = $animations;
@ -95,6 +98,8 @@ class SkinData{
return $this->skinId;
}
public function getPlayFabId() : string{ return $this->playFabId; }
public function getResourcePatch() : string{
return $this->resourcePatch;
}