diff --git a/changelogs/3.17.md b/changelogs/3.17.md new file mode 100644 index 0000000000..5e70530acf --- /dev/null +++ b/changelogs/3.17.md @@ -0,0 +1,17 @@ +**For Minecraft: Bedrock Edition 1.16.200** + +### 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.17.0 +- Added support for Minecraft: Bedrock Edition 1.16.200. +- 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 diff --git a/resources/vanilla b/resources/vanilla index 14f4a765eb..4e58a3c67d 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 14f4a765eba40b2c65c6dcd061cbfea6e1d3d4cc +Subproject commit 4e58a3c67dea62600ce5fd014b9fd792a50d246d diff --git a/src/network/mcpe/handler/PacketHandler.php b/src/network/mcpe/handler/PacketHandler.php index a37326c252..131316067a 100644 --- a/src/network/mcpe/handler/PacketHandler.php +++ b/src/network/mcpe/handler/PacketHandler.php @@ -71,6 +71,7 @@ use pocketmine\network\mcpe\protocol\EducationSettingsPacket; use pocketmine\network\mcpe\protocol\EmoteListPacket; use pocketmine\network\mcpe\protocol\EmotePacket; use pocketmine\network\mcpe\protocol\EventPacket; +use pocketmine\network\mcpe\protocol\FilterTextPacket; use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket; use pocketmine\network\mcpe\protocol\HurtArmorPacket; @@ -821,4 +822,8 @@ abstract class PacketHandler implements PacketHandlerInterface{ public function handleItemComponent(ItemComponentPacket $packet) : bool{ return false; } + + public function handleFilterText(FilterTextPacket $packet) : bool{ + return false; + } } diff --git a/src/network/mcpe/protocol/FilterTextPacket.php b/src/network/mcpe/protocol/FilterTextPacket.php new file mode 100644 index 0000000000..3d19c47a7e --- /dev/null +++ b/src/network/mcpe/protocol/FilterTextPacket.php @@ -0,0 +1,62 @@ + + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class FilterTextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ + public const NETWORK_ID = ProtocolInfo::FILTER_TEXT_PACKET; + + /** @var string */ + private $text; + /** @var bool */ + private $fromServer; + + public static function create(string $text, bool $server) : self{ + $result = new self; + $result->text = $text; + $result->fromServer = $server; + return $result; + } + + public function getText() : string{ return $this->text; } + + public function isFromServer() : bool{ return $this->fromServer; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->text = $in->getString(); + $this->fromServer = $in->getBool(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putString($this->text); + $out->putBool($this->fromServer); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleFilterText($this); + } +} diff --git a/src/network/mcpe/protocol/PacketHandlerInterface.php b/src/network/mcpe/protocol/PacketHandlerInterface.php index e53dbd7937..6ce9be8edc 100644 --- a/src/network/mcpe/protocol/PacketHandlerInterface.php +++ b/src/network/mcpe/protocol/PacketHandlerInterface.php @@ -340,4 +340,6 @@ interface PacketHandlerInterface{ public function handleCorrectPlayerMovePrediction(CorrectPlayerMovePredictionPacket $packet) : bool; public function handleItemComponent(ItemComponentPacket $packet) : bool; + + public function handleFilterText(FilterTextPacket $packet) : bool; } diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index 3e5af277c7..dc58f8db78 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -200,6 +200,7 @@ class PacketPool{ $this->registerPacket(new PlayerFogPacket()); $this->registerPacket(new CorrectPlayerMovePredictionPacket()); $this->registerPacket(new ItemComponentPacket()); + $this->registerPacket(new FilterTextPacket()); } public function registerPacket(Packet $packet) : void{ diff --git a/src/network/mcpe/protocol/ProtocolInfo.php b/src/network/mcpe/protocol/ProtocolInfo.php index adda1b5c20..d1c1183f0f 100644 --- a/src/network/mcpe/protocol/ProtocolInfo.php +++ b/src/network/mcpe/protocol/ProtocolInfo.php @@ -41,11 +41,11 @@ final class ProtocolInfo{ */ /** Actual Minecraft: PE protocol version */ - public const CURRENT_PROTOCOL = 419; + public const CURRENT_PROTOCOL = 422; /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.16.100'; + public const MINECRAFT_VERSION = 'v1.16.200'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.16.100'; + public const MINECRAFT_VERSION_NETWORK = '1.16.200'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; @@ -209,5 +209,6 @@ final class ProtocolInfo{ public const PLAYER_FOG_PACKET = 0xa0; public const CORRECT_PLAYER_MOVE_PREDICTION_PACKET = 0xa1; public const ITEM_COMPONENT_PACKET = 0xa2; + public const FILTER_TEXT_PACKET = 0xa3; } diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index e70f4f9458..ff7586bcbd 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\resourcepacks\BehaviorPackInfoEntry; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use function count; @@ -36,14 +37,14 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ public $mustAccept = false; //if true, forces client to use selected resource packs /** @var bool */ public $hasScripts = false; //if true, causes disconnect for any platform that doesn't support scripts yet - /** @var ResourcePackInfoEntry[] */ + /** @var BehaviorPackInfoEntry[] */ public $behaviorPackEntries = []; /** @var ResourcePackInfoEntry[] */ public $resourcePackEntries = []; /** * @param ResourcePackInfoEntry[] $resourcePacks - * @param ResourcePackInfoEntry[] $behaviorPacks + * @param BehaviorPackInfoEntry[] $behaviorPacks * * @return ResourcePacksInfoPacket */ @@ -61,7 +62,7 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ $this->hasScripts = $in->getBool(); $behaviorPackCount = $in->getLShort(); while($behaviorPackCount-- > 0){ - $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($in); + $this->behaviorPackEntries[] = BehaviorPackInfoEntry::read($in); } $resourcePackCount = $in->getLShort(); diff --git a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php b/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php index 516d0bfcbb..11f4bbdba8 100644 --- a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php +++ b/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php @@ -35,12 +35,15 @@ final class ItemStackResponseSlotInfo{ private $count; /** @var int */ private $itemStackId; + /** @var string */ + private $customName; - public function __construct(int $slot, int $hotbarSlot, int $count, int $itemStackId){ + public function __construct(int $slot, int $hotbarSlot, int $count, int $itemStackId, string $customName){ $this->slot = $slot; $this->hotbarSlot = $hotbarSlot; $this->count = $count; $this->itemStackId = $itemStackId; + $this->customName = $customName; } public function getSlot() : int{ return $this->slot; } @@ -51,12 +54,15 @@ final class ItemStackResponseSlotInfo{ public function getItemStackId() : int{ return $this->itemStackId; } + public function getCustomName() : string{ return $this->customName; } + public static function read(PacketSerializer $in) : self{ $slot = $in->getByte(); $hotbarSlot = $in->getByte(); $count = $in->getByte(); $itemStackId = $in->readGenericTypeNetworkId(); - return new self($slot, $hotbarSlot, $count, $itemStackId); + $customName = $in->getString(); + return new self($slot, $hotbarSlot, $count, $itemStackId, $customName); } public function write(PacketSerializer $out) : void{ @@ -64,5 +70,6 @@ final class ItemStackResponseSlotInfo{ $out->putByte($this->hotbarSlot); $out->putByte($this->count); $out->writeGenericTypeNetworkId($this->itemStackId); + $out->putString($this->customName); } } diff --git a/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php new file mode 100644 index 0000000000..df08580454 --- /dev/null +++ b/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php @@ -0,0 +1,103 @@ +packId = $packId; + $this->version = $version; + $this->sizeBytes = $sizeBytes; + $this->encryptionKey = $encryptionKey; + $this->subPackName = $subPackName; + $this->contentId = $contentId; + $this->hasScripts = $hasScripts; + } + + public function getPackId() : string{ + return $this->packId; + } + + public function getVersion() : string{ + return $this->version; + } + + public function getSizeBytes() : int{ + return $this->sizeBytes; + } + + public function getEncryptionKey() : string{ + return $this->encryptionKey; + } + + public function getSubPackName() : string{ + return $this->subPackName; + } + + public function getContentId() : string{ + return $this->contentId; + } + + public function hasScripts() : bool{ + return $this->hasScripts; + } + + public function write(PacketSerializer $out) : void{ + $out->putString($this->packId); + $out->putString($this->version); + $out->putLLong($this->sizeBytes); + $out->putString($this->encryptionKey); + $out->putString($this->subPackName); + $out->putString($this->contentId); + $out->putBool($this->hasScripts); + } + + public static function read(PacketSerializer $in) : self{ + $uuid = $in->getString(); + $version = $in->getString(); + $sizeBytes = $in->getLLong(); + $encryptionKey = $in->getString(); + $subPackName = $in->getString(); + $contentId = $in->getString(); + $hasScripts = $in->getBool(); + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts); + } +} diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index 5ea031b5cc..9be7072ba1 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -41,8 +41,10 @@ class ResourcePackInfoEntry{ private $contentId; /** @var bool */ private $hasScripts; + /** @var bool */ + private $isRtxCapable; - public function __construct(string $packId, string $version, int $sizeBytes, string $encryptionKey = "", string $subPackName = "", string $contentId = "", bool $hasScripts = false){ + public function __construct(string $packId, string $version, int $sizeBytes, string $encryptionKey = "", string $subPackName = "", string $contentId = "", bool $hasScripts = false, bool $isRtxCapable = false){ $this->packId = $packId; $this->version = $version; $this->sizeBytes = $sizeBytes; @@ -50,6 +52,7 @@ class ResourcePackInfoEntry{ $this->subPackName = $subPackName; $this->contentId = $contentId; $this->hasScripts = $hasScripts; + $this->isRtxCapable = $isRtxCapable; } public function getPackId() : string{ @@ -80,6 +83,8 @@ class ResourcePackInfoEntry{ return $this->hasScripts; } + public function isRtxCapable() : bool{ return $this->isRtxCapable; } + public function write(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putString($this->version); @@ -88,6 +93,7 @@ class ResourcePackInfoEntry{ $out->putString($this->subPackName); $out->putString($this->contentId); $out->putBool($this->hasScripts); + $out->putBool($this->isRtxCapable); } public static function read(PacketSerializer $in) : self{ @@ -98,6 +104,7 @@ class ResourcePackInfoEntry{ $subPackName = $in->getString(); $contentId = $in->getString(); $hasScripts = $in->getBool(); - return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts); + $rtxCapable = $in->getBool(); + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $rtxCapable); } }