From 70636f6eb4a7c487e2f43ee9673b338bcc88b94d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Oct 2021 18:00:34 +0100 Subject: [PATCH 1/3] Protocol changes for 1.17.40 --- .../network/mcpe/NetworkSession.php | 14 ++- .../network/mcpe/protocol/PacketPool.php | 4 +- ...JumpPacket.php => PassengerJumpPacket.php} | 8 +- .../network/mcpe/protocol/ProtocolInfo.php | 10 +- .../network/mcpe/protocol/SubChunkPacket.php | 109 ++++++++++++++++++ .../mcpe/protocol/SubChunkRequestPacket.php | 72 ++++++++++++ .../types/SubChunkPacketHeightMapInfo.php | 89 ++++++++++++++ .../types/SubChunkPacketHeightMapType.php | 32 +++++ .../protocol/types/SubChunkRequestResult.php | 34 ++++++ src/pocketmine/resources/vanilla | 2 +- 10 files changed, 362 insertions(+), 12 deletions(-) rename src/pocketmine/network/mcpe/protocol/{RiderJumpPacket.php => PassengerJumpPacket.php} (83%) create mode 100644 src/pocketmine/network/mcpe/protocol/SubChunkPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/SubChunkRequestPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapInfo.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapType.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/SubChunkRequestResult.php diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c0584ddb4..f505e1ec1 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -116,6 +116,7 @@ use pocketmine\network\mcpe\protocol\NpcDialoguePacket; use pocketmine\network\mcpe\protocol\NpcRequestPacket; use pocketmine\network\mcpe\protocol\OnScreenTextureAnimationPacket; use pocketmine\network\mcpe\protocol\PacketViolationWarningPacket; +use pocketmine\network\mcpe\protocol\PassengerJumpPacket; use pocketmine\network\mcpe\protocol\PhotoInfoRequestPacket; use pocketmine\network\mcpe\protocol\PhotoTransferPacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; @@ -144,7 +145,6 @@ use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; -use pocketmine\network\mcpe\protocol\RiderJumpPacket; use pocketmine\network\mcpe\protocol\ScriptCustomEventPacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket; @@ -178,6 +178,8 @@ use pocketmine\network\mcpe\protocol\StopSoundPacket; use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataRequestPacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataResponsePacket; +use pocketmine\network\mcpe\protocol\SubChunkPacket; +use pocketmine\network\mcpe\protocol\SubChunkRequestPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\SyncActorPropertyPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; @@ -272,7 +274,7 @@ abstract class NetworkSession{ return false; } - public function handleRiderJump(RiderJumpPacket $packet) : bool{ + public function handlePassengerJump(PassengerJumpPacket $packet) : bool{ return false; } @@ -871,4 +873,12 @@ abstract class NetworkSession{ public function handlePhotoInfoRequest(PhotoInfoRequestPacket $packet) : bool{ return false; } + + public function handleSubChunk(SubChunkPacket $packet) : bool{ + return false; + } + + public function handleSubChunkRequest(SubChunkRequestPacket $packet) : bool{ + return false; + } } diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index 531db9052..0ea0ff53a 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -54,7 +54,7 @@ class PacketPool{ static::registerPacket(new TakeItemActorPacket()); static::registerPacket(new MoveActorAbsolutePacket()); static::registerPacket(new MovePlayerPacket()); - static::registerPacket(new RiderJumpPacket()); + static::registerPacket(new PassengerJumpPacket()); static::registerPacket(new UpdateBlockPacket()); static::registerPacket(new AddPaintingPacket()); static::registerPacket(new TickSyncPacket()); @@ -204,6 +204,8 @@ class PacketPool{ static::registerPacket(new CreatePhotoPacket()); static::registerPacket(new UpdateSubChunkBlocksPacket()); static::registerPacket(new PhotoInfoRequestPacket()); + static::registerPacket(new SubChunkPacket()); + static::registerPacket(new SubChunkRequestPacket()); } /** diff --git a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php b/src/pocketmine/network/mcpe/protocol/PassengerJumpPacket.php similarity index 83% rename from src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php rename to src/pocketmine/network/mcpe/protocol/PassengerJumpPacket.php index ba108848c..11b286c99 100644 --- a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PassengerJumpPacket.php @@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; -class RiderJumpPacket extends DataPacket{ - public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; +class PassengerJumpPacket extends DataPacket{ + public const NETWORK_ID = ProtocolInfo::PASSENGER_JUMP_PACKET; /** @var int */ public $jumpStrength; //percentage @@ -41,7 +41,7 @@ class RiderJumpPacket extends DataPacket{ $this->putVarInt($this->jumpStrength); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRiderJump($this); + public function handle(NetworkSession $handler) : bool{ + return $handler->handlePassengerJump($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index 7d1cbc077..94012727b 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -37,11 +37,11 @@ interface ProtocolInfo{ */ /** Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 465; + public const CURRENT_PROTOCOL = 471; /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.17.30'; + public const MINECRAFT_VERSION = 'v1.17.40'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.17.30'; + public const MINECRAFT_VERSION_NETWORK = '1.17.40'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; @@ -62,7 +62,7 @@ interface ProtocolInfo{ public const TAKE_ITEM_ACTOR_PACKET = 0x11; public const MOVE_ACTOR_ABSOLUTE_PACKET = 0x12; public const MOVE_PLAYER_PACKET = 0x13; - public const RIDER_JUMP_PACKET = 0x14; + public const PASSENGER_JUMP_PACKET = 0x14; public const UPDATE_BLOCK_PACKET = 0x15; public const ADD_PAINTING_PACKET = 0x16; public const TICK_SYNC_PACKET = 0x17; @@ -216,5 +216,7 @@ interface ProtocolInfo{ public const CREATE_PHOTO_PACKET = 0xab; public const UPDATE_SUB_CHUNK_BLOCKS_PACKET = 0xac; public const PHOTO_INFO_REQUEST_PACKET = 0xad; + public const SUB_CHUNK_PACKET = 0xae; + public const SUB_CHUNK_REQUEST_PACKET = 0xaf; } diff --git a/src/pocketmine/network/mcpe/protocol/SubChunkPacket.php b/src/pocketmine/network/mcpe/protocol/SubChunkPacket.php new file mode 100644 index 000000000..35d4be5f4 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/SubChunkPacket.php @@ -0,0 +1,109 @@ + + +use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\types\SubChunkPacketHeightMapInfo; +use pocketmine\network\mcpe\protocol\types\SubChunkPacketHeightMapType; + +class SubChunkPacket extends DataPacket{ + public const NETWORK_ID = ProtocolInfo::SUB_CHUNK_PACKET; + + private int $dimension; + private int $subChunkX; + private int $subChunkY; + private int $subChunkZ; + private string $data; + private int $requestResult; + private ?SubChunkPacketHeightMapInfo $heightMapData = null; + + public static function create(int $dimension, int $subChunkX, int $subChunkY, int $subChunkZ, string $data, int $requestResult, ?SubChunkPacketHeightMapInfo $heightMapData) : self{ + $result = new self; + $result->dimension = $dimension; + $result->subChunkX = $subChunkX; + $result->subChunkY = $subChunkY; + $result->subChunkZ = $subChunkZ; + $result->data = $data; + $result->requestResult = $requestResult; + $result->heightMapData = $heightMapData; + return $result; + } + + public function getDimension() : int{ return $this->dimension; } + + public function getSubChunkX() : int{ return $this->subChunkX; } + + public function getSubChunkY() : int{ return $this->subChunkY; } + + public function getSubChunkZ() : int{ return $this->subChunkZ; } + + public function getData() : string{ return $this->data; } + + public function getRequestResult() : int{ return $this->requestResult; } + + public function getHeightMapData() : ?SubChunkPacketHeightMapInfo{ return $this->heightMapData; } + + protected function decodePayload() : void{ + $this->dimension = $this->getVarInt(); + $this->subChunkX = $this->getVarInt(); + $this->subChunkY = $this->getVarInt(); + $this->subChunkZ = $this->getVarInt(); + $this->data = $this->getString(); + $this->requestResult = $this->getVarInt(); + $heightMapDataType = $this->getByte(); + $this->heightMapData = match($heightMapDataType){ + SubChunkPacketHeightMapType::NO_DATA => null, + SubChunkPacketHeightMapType::DATA => SubChunkPacketHeightMapInfo::read($this), + SubChunkPacketHeightMapType::ALL_TOO_HIGH => SubChunkPacketHeightMapInfo::allTooHigh(), + SubChunkPacketHeightMapType::ALL_TOO_LOW => SubChunkPacketHeightMapInfo::allTooLow(), + default => throw new \UnexpectedValueException("Unknown heightmap data type $heightMapDataType") + }; + } + + protected function encodePayload() : void{ + $this->putVarInt($this->dimension); + $this->putVarInt($this->subChunkX); + $this->putVarInt($this->subChunkY); + $this->putVarInt($this->subChunkZ); + $this->putString($this->data); + $this->putVarInt($this->requestResult); + if($this->heightMapData === null){ + $this->putByte(SubChunkPacketHeightMapType::NO_DATA); + }elseif($this->heightMapData->isAllTooLow()){ + $this->putByte(SubChunkPacketHeightMapType::ALL_TOO_LOW); + }elseif($this->heightMapData->isAllTooHigh()){ + $this->putByte(SubChunkPacketHeightMapType::ALL_TOO_HIGH); + }else{ + $heightMapData = $this->heightMapData; //avoid PHPStan purity issue + $this->putByte(SubChunkPacketHeightMapType::DATA); + $heightMapData->write($this); + } + } + + public function handle(NetworkSession $handler) : bool{ + return $handler->handleSubChunk($this); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/SubChunkRequestPacket.php b/src/pocketmine/network/mcpe/protocol/SubChunkRequestPacket.php new file mode 100644 index 000000000..cd3594576 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/SubChunkRequestPacket.php @@ -0,0 +1,72 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class SubChunkRequestPacket extends DataPacket/* implements ServerboundPacket*/{ + public const NETWORK_ID = ProtocolInfo::SUB_CHUNK_REQUEST_PACKET; + + private int $dimension; + private int $subChunkX; + private int $subChunkY; + private int $subChunkZ; + + public static function create(int $dimension, int $subChunkX, int $subChunkY, int $subChunkZ) : self{ + $result = new self; + $result->dimension = $dimension; + $result->subChunkX = $subChunkX; + $result->subChunkY = $subChunkY; + $result->subChunkZ = $subChunkZ; + return $result; + } + + public function getDimension() : int{ return $this->dimension; } + + public function getSubChunkX() : int{ return $this->subChunkX; } + + public function getSubChunkY() : int{ return $this->subChunkY; } + + public function getSubChunkZ() : int{ return $this->subChunkZ; } + + protected function decodePayload() : void{ + $this->dimension = $this->getVarInt(); + $this->subChunkX = $this->getVarInt(); + $this->subChunkY = $this->getVarInt(); + $this->subChunkZ = $this->getVarInt(); + } + + protected function encodePayload() : void{ + $this->putVarInt($this->dimension); + $this->putVarInt($this->subChunkX); + $this->putVarInt($this->subChunkY); + $this->putVarInt($this->subChunkZ); + } + + public function handle(NetworkSession $handler) : bool{ + return $handler->handleSubChunkRequest($this); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapInfo.php b/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapInfo.php new file mode 100644 index 000000000..d8934d744 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapInfo.php @@ -0,0 +1,89 @@ + $heights + */ + public function __construct(private array $heights){ + if(count($heights) !== 256){ + throw new \InvalidArgumentException("Expected exactly 256 heightmap values"); + } + } + + /** @return int[] */ + public function getHeights() : array{ return $this->heights; } + + public function getHeight(int $x, int $z) : int{ + return $this->heights[(($z & 0xf) << 4) | ($x & 0xf)]; + } + + public static function read(NetworkBinaryStream $in) : self{ + $heights = []; + for($i = 0; $i < 256; ++$i){ + $heights[] = Binary::signByte($in->getByte()); + } + return new self($heights); + } + + public function write(NetworkBinaryStream $out) : void{ + for($i = 0; $i < 256; ++$i){ + $out->putByte(Binary::unsignByte($this->heights[$i])); + } + } + + public static function allTooLow() : self{ + return new self(array_fill(0, 256, -1)); + } + + public static function allTooHigh() : self{ + return new self(array_fill(0, 256, 16)); + } + + public function isAllTooLow() : bool{ + foreach($this->heights as $height){ + if($height >= 0){ + return false; + } + } + return true; + } + + public function isAllTooHigh() : bool{ + foreach($this->heights as $height){ + if($height <= 15){ + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapType.php b/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapType.php new file mode 100644 index 000000000..7b1d4105d --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/SubChunkPacketHeightMapType.php @@ -0,0 +1,32 @@ + Date: Tue, 19 Oct 2021 18:27:26 +0100 Subject: [PATCH 2/3] Release 3.25.0 --- changelogs/3.25.md | 11 +++++++++++ src/pocketmine/VersionInfo.php | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 changelogs/3.25.md diff --git a/changelogs/3.25.md b/changelogs/3.25.md new file mode 100644 index 000000000..8c66ff9f3 --- /dev/null +++ b/changelogs/3.25.md @@ -0,0 +1,11 @@ +**For Minecraft: Bedrock Edition 1.17.40** + +### 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.25.0 +- Added support for Minecraft: Bedrock Edition 1.17.40. +- Removed compatibility with earlier versions. diff --git a/src/pocketmine/VersionInfo.php b/src/pocketmine/VersionInfo.php index a13e9cce1..268ca7749 100644 --- a/src/pocketmine/VersionInfo.php +++ b/src/pocketmine/VersionInfo.php @@ -33,7 +33,7 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ const _VERSION_INFO_INCLUDED = true; const NAME = "PocketMine-MP"; -const BASE_VERSION = "3.24.1"; -const IS_DEVELOPMENT_BUILD = true; +const BASE_VERSION = "3.25.0"; +const IS_DEVELOPMENT_BUILD = false; const BUILD_NUMBER = 0; -const BUILD_CHANNEL = ""; +const BUILD_CHANNEL = "stable"; From 9c5cec77b177318e3559d4a37cf0d6da84bd265b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Oct 2021 18:27:30 +0100 Subject: [PATCH 3/3] 3.25.1 is next --- src/pocketmine/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/VersionInfo.php b/src/pocketmine/VersionInfo.php index 268ca7749..82af4e6ce 100644 --- a/src/pocketmine/VersionInfo.php +++ b/src/pocketmine/VersionInfo.php @@ -33,7 +33,7 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ const _VERSION_INFO_INCLUDED = true; const NAME = "PocketMine-MP"; -const BASE_VERSION = "3.25.0"; -const IS_DEVELOPMENT_BUILD = false; +const BASE_VERSION = "3.25.1"; +const IS_DEVELOPMENT_BUILD = true; const BUILD_NUMBER = 0; -const BUILD_CHANNEL = "stable"; +const BUILD_CHANNEL = "";