mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-03 18:42:37 +00:00
Merge branch 'stable'
This commit is contained in:
commit
3fe0adbd7f
18
changelogs/3.18.md
Normal file
18
changelogs/3.18.md
Normal 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
|
@ -50,6 +50,7 @@ class LegacySkinAdapter implements SkinAdapter{
|
||||
}
|
||||
return new SkinData(
|
||||
$skin->getSkinId(),
|
||||
"", //TODO: playfab ID
|
||||
$resourcePatch,
|
||||
SkinImage::fromLegacy($skin->getSkinData()), [],
|
||||
$capeImage,
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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{
|
||||
|
137
src/network/mcpe/protocol/ClientboundDebugRendererPacket.php
Normal file
137
src/network/mcpe/protocol/ClientboundDebugRendererPacket.php
Normal 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);
|
||||
}
|
||||
}
|
@ -342,4 +342,6 @@ interface PacketHandlerInterface{
|
||||
public function handleItemComponent(ItemComponentPacket $packet) : bool;
|
||||
|
||||
public function handleFilterText(FilterTextPacket $packet) : bool;
|
||||
|
||||
public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool;
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
|
61
src/network/mcpe/protocol/types/PlayerMovementSettings.php
Normal file
61
src/network/mcpe/protocol/types/PlayerMovementSettings.php
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,9 @@ final class ClientData{
|
||||
|
||||
public string $PlatformUserId = ""; //xbox-only, apparently
|
||||
|
||||
/** @required */
|
||||
public string $PlayFabId;
|
||||
|
||||
/** @required */
|
||||
public bool $PremiumSkin = false;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user