diff --git a/build/php b/build/php index 1e92da1b9..45ab9b078 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 1e92da1b9525dbcb434d381188019139ed05147b +Subproject commit 45ab9b0781e78e23e1fd919e8137dbf33c7e7abb diff --git a/changelogs/3.19.md b/changelogs/3.19.md index 0901687e0..aaa950525 100644 --- a/changelogs/3.19.md +++ b/changelogs/3.19.md @@ -24,3 +24,8 @@ Plugin developers should **only** update their required API to this version if y # 3.19.2 - Signs can now only be edited by the player who placed them. They will become finalized if the chunk containing them is unloaded and reloaded, or if the creating player quits the server. + +# 3.19.3 +- Fixed `Worker->quit()` returning without stopping the thread. +- Added some protocol constants in `SetDisplayObjectivePacket`. +- Fixed possible client crash caused by `CraftingDataPacket`. diff --git a/composer.lock b/composer.lock index 7940dfa2e..dda295418 100644 --- a/composer.lock +++ b/composer.lock @@ -1154,16 +1154,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -1175,7 +1175,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1213,7 +1213,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" }, "funding": [ { @@ -1229,7 +1229,7 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2318,16 +2318,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.4", + "version": "9.5.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c73c6737305e779771147af66c96ca6a7ed8a741" + "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741", - "reference": "c73c6737305e779771147af66c96ca6a7ed8a741", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/89ff45ea9d70e35522fb6654a2ebc221158de276", + "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276", "shasum": "" }, "require": { @@ -2357,7 +2357,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3", + "sebastian/type": "^2.3.2", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -2405,7 +2405,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.4" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.5" }, "funding": [ { @@ -2417,7 +2417,7 @@ "type": "github" } ], - "time": "2021-03-23T07:16:29+00:00" + "time": "2021-06-05T04:49:07+00:00" }, { "name": "sebastian/cli-parser", @@ -3276,16 +3276,16 @@ }, { "name": "sebastian/type", - "version": "2.3.1", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" + "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0d1c587401514d17e8f9258a27e23527cb1b06c1", + "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1", "shasum": "" }, "require": { @@ -3320,7 +3320,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" + "source": "https://github.com/sebastianbergmann/type/tree/2.3.2" }, "funding": [ { @@ -3328,7 +3328,7 @@ "type": "github" } ], - "time": "2020-10-26T13:18:59+00:00" + "time": "2021-06-04T13:02:07+00:00" }, { "name": "sebastian/version", diff --git a/resources/vanilla b/resources/vanilla index 989e02a63..04c846c5f 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 989e02a6318b1278fda8526dd136749b9b7b34b4 +Subproject commit 04c846c5f95a7bb9ae111f699f2ba08c9ec838aa diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index f1d2a3ebd..30a53ebd1 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -86,6 +86,10 @@ final class ItemTranslator{ if(!is_string($oldId) || !is_string($newId)){ throw new AssumptionFailedError("Invalid item table format"); } + if(!isset($legacyStringToIntMap[$oldId])){ + //new item without a fixed legacy ID - we can't handle this right now + continue; + } $simpleMappings[$newId] = $legacyStringToIntMap[$oldId]; } foreach($legacyStringToIntMap as $stringId => $intId){ @@ -129,8 +133,9 @@ final class ItemTranslator{ }elseif(isset($simpleMappings[$stringId])){ $this->simpleCoreToNetMapping[$simpleMappings[$stringId]] = $netId; $this->simpleNetToCoreMapping[$netId] = $simpleMappings[$stringId]; - }elseif($stringId !== "minecraft:unknown"){ - throw new \InvalidArgumentException("Unmapped entry " . $stringId); + }else{ + //not all items have a legacy mapping - for now, we only support the ones that do + continue; } } } diff --git a/src/network/mcpe/handler/PacketHandler.php b/src/network/mcpe/handler/PacketHandler.php index e97e1673d..b1f5d162b 100644 --- a/src/network/mcpe/handler/PacketHandler.php +++ b/src/network/mcpe/handler/PacketHandler.php @@ -31,6 +31,7 @@ use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\AddPaintingPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket; +use pocketmine\network\mcpe\protocol\AddVolumeEntityPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimateEntityPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; @@ -130,6 +131,7 @@ use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\RemoveObjectivePacket; +use pocketmine\network\mcpe\protocol\RemoveVolumeEntityPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; @@ -172,6 +174,7 @@ use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataRequestPacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataResponsePacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; +use pocketmine\network\mcpe\protocol\SyncActorPropertyPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TickSyncPacket; @@ -831,4 +834,16 @@ abstract class PacketHandler implements PacketHandlerInterface{ public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool{ return false; } + + public function handleSyncActorProperty(SyncActorPropertyPacket $packet) : bool{ + return false; + } + + public function handleAddVolumeEntity(AddVolumeEntityPacket $packet) : bool{ + return false; + } + + public function handleRemoveVolumeEntity(RemoveVolumeEntityPacket $packet) : bool{ + return false; + } } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index a52f86e73..a6f52af3e 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -38,6 +38,8 @@ use pocketmine\network\mcpe\protocol\types\PlayerMovementType; use pocketmine\network\mcpe\protocol\types\SpawnSettings; use pocketmine\player\Player; use pocketmine\Server; +use pocketmine\VersionInfo; +use function sprintf; /** * Handler used for the pre-spawn phase of the session. @@ -82,13 +84,14 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->lightningLevel = 0; $pk->commandsEnabled = true; $pk->gameRules = [ - "naturalregeneration" => new BoolGameRule(false) //Hack for client side regeneration + "naturalregeneration" => new BoolGameRule(false, false) //Hack for client side regeneration ]; $pk->experiments = new Experiments([], false); $pk->levelId = ""; $pk->worldName = $this->server->getMotd(); $pk->itemTable = GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries(); //TODO: check if this is actually needed $pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false); + $pk->serverSoftwareVersion = sprintf("%s %s", VersionInfo::NAME, VersionInfo::getVersionObj()->getFullVersion(true)); $this->session->sendDataPacket($pk); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); diff --git a/src/network/mcpe/protocol/AddVolumeEntityPacket.php b/src/network/mcpe/protocol/AddVolumeEntityPacket.php new file mode 100644 index 000000000..612fe9042 --- /dev/null +++ b/src/network/mcpe/protocol/AddVolumeEntityPacket.php @@ -0,0 +1,65 @@ + + +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class AddVolumeEntityPacket extends DataPacket implements ClientboundPacket{ + public const NETWORK_ID = ProtocolInfo::ADD_VOLUME_ENTITY_PACKET; + + /** @var int */ + private $entityNetId; + /** @var CompoundTag */ + private $data; + + public static function create(int $entityNetId, CompoundTag $data) : self{ + $result = new self; + $result->entityNetId = $entityNetId; + $result->data = $data; + return $result; + } + + public function getEntityNetId() : int{ return $this->entityNetId; } + + public function getData() : CompoundTag{ return $this->data; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->entityNetId = $in->getUnsignedVarInt(); + $this->data = $in->getNbtCompoundRoot(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putUnsignedVarInt($this->entityNetId); + $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->data))); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleAddVolumeEntity($this); + } +} diff --git a/src/network/mcpe/protocol/PacketHandlerInterface.php b/src/network/mcpe/protocol/PacketHandlerInterface.php index 9452ef030..5a27d0a54 100644 --- a/src/network/mcpe/protocol/PacketHandlerInterface.php +++ b/src/network/mcpe/protocol/PacketHandlerInterface.php @@ -344,4 +344,10 @@ interface PacketHandlerInterface{ public function handleFilterText(FilterTextPacket $packet) : bool; public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool; + + public function handleSyncActorProperty(SyncActorPropertyPacket $packet) : bool; + + public function handleAddVolumeEntity(AddVolumeEntityPacket $packet) : bool; + + public function handleRemoveVolumeEntity(RemoveVolumeEntityPacket $packet) : bool; } diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index dc0713f9c..b7d750079 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -202,6 +202,9 @@ class PacketPool{ $this->registerPacket(new ItemComponentPacket()); $this->registerPacket(new FilterTextPacket()); $this->registerPacket(new ClientboundDebugRendererPacket()); + $this->registerPacket(new SyncActorPropertyPacket()); + $this->registerPacket(new AddVolumeEntityPacket()); + $this->registerPacket(new RemoveVolumeEntityPacket()); } public function registerPacket(Packet $packet) : void{ diff --git a/src/network/mcpe/protocol/ProtocolInfo.php b/src/network/mcpe/protocol/ProtocolInfo.php index 7cc178699..c902b5214 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 = 431; + public const CURRENT_PROTOCOL = 440; /** Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - public const MINECRAFT_VERSION = 'v1.16.220'; + public const MINECRAFT_VERSION = 'v1.17.0'; /** Version number sent to clients in ping responses. */ - public const MINECRAFT_VERSION_NETWORK = '1.16.220'; + public const MINECRAFT_VERSION_NETWORK = '1.17.0'; public const LOGIN_PACKET = 0x01; public const PLAY_STATUS_PACKET = 0x02; @@ -211,5 +211,8 @@ final class ProtocolInfo{ public const ITEM_COMPONENT_PACKET = 0xa2; public const FILTER_TEXT_PACKET = 0xa3; public const CLIENTBOUND_DEBUG_RENDERER_PACKET = 0xa4; + public const SYNC_ACTOR_PROPERTY_PACKET = 0xa5; + public const ADD_VOLUME_ENTITY_PACKET = 0xa6; + public const REMOVE_VOLUME_ENTITY_PACKET = 0xa7; } diff --git a/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php b/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php new file mode 100644 index 000000000..3f5c069f4 --- /dev/null +++ b/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php @@ -0,0 +1,55 @@ + + +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class RemoveVolumeEntityPacket extends DataPacket{ + public const NETWORK_ID = ProtocolInfo::REMOVE_VOLUME_ENTITY_PACKET; + + /** @var int */ + private $entityNetId; + + public static function create(int $entityNetId) : self{ + $result = new self; + $result->entityNetId = $entityNetId; + return $result; + } + + public function getEntityNetId() : int{ return $this->entityNetId; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->entityNetId = $in->getUnsignedVarInt(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->putUnsignedVarInt($this->entityNetId); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleRemoveVolumeEntity($this); + } +} diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 0b490ba10..2a7ee064f 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -163,6 +163,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort /** @var bool */ public $enableNewInventorySystem = false; //TODO + /** @var string */ + public $serverSoftwareVersion; /** * @var BlockPaletteEntry[] @@ -256,6 +258,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $this->multiplayerCorrelationId = $in->getString(); $this->enableNewInventorySystem = $in->getBool(); + $this->serverSoftwareVersion = $in->getString(); } protected function encodePayload(PacketSerializer $out) : void{ @@ -336,6 +339,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $out->putString($this->multiplayerCorrelationId); $out->putBool($this->enableNewInventorySystem); + $out->putString($this->serverSoftwareVersion); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/SyncActorPropertyPacket.php b/src/network/mcpe/protocol/SyncActorPropertyPacket.php new file mode 100644 index 000000000..de547f4e9 --- /dev/null +++ b/src/network/mcpe/protocol/SyncActorPropertyPacket.php @@ -0,0 +1,58 @@ + + +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; + +class SyncActorPropertyPacket extends DataPacket{ + public const NETWORK_ID = ProtocolInfo::SYNC_ACTOR_PROPERTY_PACKET; + + /** @var CompoundTag */ + private $data; + + public static function create(CompoundTag $data) : self{ + $result = new self; + $result->data = $data; + return $result; + } + + public function getData() : CompoundTag{ return $this->data; } + + protected function decodePayload(PacketSerializer $in) : void{ + $this->data = $in->getNbtCompoundRoot(); + } + + protected function encodePayload(PacketSerializer $out) : void{ + $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->data))); + } + + public function handle(PacketHandlerInterface $handler) : bool{ + return $handler->handleSyncActorProperty($this); + } +} diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index c2b649060..1f2ad2278 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -597,11 +597,11 @@ class PacketSerializer extends BinaryStream{ $this->putByte((int) ($rotation / (360 / 256))); } - private function readGameRule(int $type) : GameRule{ + private function readGameRule(int $type, bool $isPlayerModifiable) : GameRule{ switch($type){ - case GameRuleType::BOOL: return BoolGameRule::decode($this); - case GameRuleType::INT: return IntGameRule::decode($this); - case GameRuleType::FLOAT: return FloatGameRule::decode($this); + case GameRuleType::BOOL: return BoolGameRule::decode($this, $isPlayerModifiable); + case GameRuleType::INT: return IntGameRule::decode($this, $isPlayerModifiable); + case GameRuleType::FLOAT: return FloatGameRule::decode($this, $isPlayerModifiable); default: throw new PacketDecodeException("Unknown gamerule type $type"); } @@ -621,8 +621,9 @@ class PacketSerializer extends BinaryStream{ $rules = []; for($i = 0; $i < $count; ++$i){ $name = $this->getString(); + $isPlayerModifiable = $this->getBool(); $type = $this->getUnsignedVarInt(); - $rules[$name] = $this->readGameRule($type); + $rules[$name] = $this->readGameRule($type, $isPlayerModifiable); } return $rules; @@ -638,6 +639,7 @@ class PacketSerializer extends BinaryStream{ $this->putUnsignedVarInt(count($rules)); foreach($rules as $name => $rule){ $this->putString($name); + $this->putBool($rule->isPlayerModifiable()); $this->putUnsignedVarInt($rule->getType()); $rule->encode($this); } diff --git a/src/network/mcpe/protocol/types/BoolGameRule.php b/src/network/mcpe/protocol/types/BoolGameRule.php index c4fbe7290..c26b2c916 100644 --- a/src/network/mcpe/protocol/types/BoolGameRule.php +++ b/src/network/mcpe/protocol/types/BoolGameRule.php @@ -30,7 +30,8 @@ final class BoolGameRule extends GameRule{ /** @var bool */ private $value; - public function __construct(bool $value){ + public function __construct(bool $value, bool $isPlayerModifiable){ + parent::__construct($isPlayerModifiable); $this->value = $value; } @@ -46,7 +47,7 @@ final class BoolGameRule extends GameRule{ $out->putBool($this->value); } - public static function decode(PacketSerializer $in) : self{ - return new self($in->getBool()); + public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ + return new self($in->getBool(), $isPlayerModifiable); } } diff --git a/src/network/mcpe/protocol/types/FloatGameRule.php b/src/network/mcpe/protocol/types/FloatGameRule.php index d614d36a2..caab87c3a 100644 --- a/src/network/mcpe/protocol/types/FloatGameRule.php +++ b/src/network/mcpe/protocol/types/FloatGameRule.php @@ -29,7 +29,8 @@ final class FloatGameRule extends GameRule{ /** @var float */ private $value; - public function __construct(float $value){ + public function __construct(float $value, bool $isPlayerModifiable){ + parent::__construct($isPlayerModifiable); $this->value = $value; } @@ -45,7 +46,7 @@ final class FloatGameRule extends GameRule{ $out->putLFloat($this->value); } - public static function decode(PacketSerializer $in) : self{ - return new self($in->getLFloat()); + public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ + return new self($in->getLFloat(), $isPlayerModifiable); } } diff --git a/src/network/mcpe/protocol/types/GameRule.php b/src/network/mcpe/protocol/types/GameRule.php index b578524a2..dfa8c1fb1 100644 --- a/src/network/mcpe/protocol/types/GameRule.php +++ b/src/network/mcpe/protocol/types/GameRule.php @@ -27,6 +27,14 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; abstract class GameRule{ + private bool $playerModifiable; + + public function __construct(bool $isPlayerModifiable){ + $this->playerModifiable = $isPlayerModifiable; + } + + public function isPlayerModifiable() : bool{ return $this->playerModifiable; } + abstract public function getType() : int; abstract public function encode(PacketSerializer $out) : void; diff --git a/src/network/mcpe/protocol/types/IntGameRule.php b/src/network/mcpe/protocol/types/IntGameRule.php index c982aa457..bf199c597 100644 --- a/src/network/mcpe/protocol/types/IntGameRule.php +++ b/src/network/mcpe/protocol/types/IntGameRule.php @@ -30,7 +30,8 @@ final class IntGameRule extends GameRule{ /** @var int */ private $value; - public function __construct(int $value){ + public function __construct(int $value, bool $isPlayerModifiable){ + parent::__construct($isPlayerModifiable); $this->value = $value; } @@ -46,7 +47,7 @@ final class IntGameRule extends GameRule{ $out->putUnsignedVarInt($this->value); } - public static function decode(PacketSerializer $in) : self{ - return new self($in->getUnsignedVarInt()); + public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ + return new self($in->getUnsignedVarInt(), $isPlayerModifiable); } }