diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b93234287..1e6c9474f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -112,7 +112,6 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; @@ -1959,11 +1958,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; } - public function handleBatch(BatchPacket $packet) : bool{ - $this->server->getNetwork()->processBatch($packet, $this); - return true; - } - public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{ return false; } @@ -3303,6 +3297,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); + $packet->decode(); + assert($packet->feof(), "Still " . strlen(substr($packet->buffer, $packet->offset)) . " bytes unread in " . get_class($packet)); + $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet)); if(!$ev->isCancelled() and !$packet->handle($this)){ $this->server->getLogger()->debug("Unhandled " . get_class($packet) . " received from " . $this->getName()); diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index d7dfc7a3a..1a16800a3 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -55,16 +55,15 @@ use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\network\mcpe\protocol\HurtArmorPacket; -use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; -use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryActionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LoginPacket; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; +use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; +use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\MoveEntityPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; @@ -72,6 +71,7 @@ use pocketmine\network\mcpe\protocol\PlayerFallPacket; use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\RemoveBlockPacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\ReplaceItemInSlotPacket; @@ -103,9 +103,7 @@ use pocketmine\network\mcpe\protocol\UnknownPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\protocol\UpdateTradePacket; use pocketmine\network\mcpe\protocol\UseItemPacket; -use pocketmine\Player; use pocketmine\Server; -use pocketmine\utils\BinaryStream; class Network{ @@ -232,50 +230,6 @@ class Network{ return $this->server; } - /** - * Decodes a batch packet and does handling for it. - * - * TODO: Move this out of here - * - * @param BatchPacket $packet - * @param Player $player - * - * @throws \InvalidArgumentException|\InvalidStateException - */ - public function processBatch(BatchPacket $packet, Player $p){ - $rawLen = strlen($packet->payload); - if($rawLen === 0){ - throw new \InvalidArgumentException("BatchPacket payload is empty or packet decode error"); - }elseif($rawLen < 3){ - throw new \InvalidArgumentException("Not enough bytes, expected zlib header"); - } - - $str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB - $len = strlen($str); - - if($len === 0){ - throw new \InvalidStateException("Decoded BatchPacket payload is empty"); - } - - $stream = new BinaryStream($str); - - while($stream->offset < $len){ - $buf = $stream->getString(); - - if(($pk = $this->getPacket(ord($buf{0}))) !== null){ - if(!$pk->canBeBatched()){ - throw new \InvalidStateException("Received invalid " . get_class($pk) . " inside BatchPacket"); - } - - $pk->setBuffer($buf, 1); - - $pk->decode(); - assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread in " . get_class($pk)); - $p->handleDataPacket($pk); - } - } - } - /** * @param $id * diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index ae790ae9e..66d19d063 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -32,7 +32,6 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; @@ -47,6 +46,7 @@ use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket; +use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\DropItemPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; @@ -103,9 +103,17 @@ use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\protocol\UpdateTradePacket; use pocketmine\network\mcpe\protocol\UseItemPacket; +use pocketmine\Server; interface NetworkSession{ + /** + * @return Server + */ + public function getServer(); + + public function handleDataPacket(DataPacket $pk); + public function handleLogin(LoginPacket $packet) : bool; public function handlePlayStatus(PlayStatusPacket $packet) : bool; @@ -116,8 +124,6 @@ interface NetworkSession{ public function handleDisconnect(DisconnectPacket $packet) : bool; - public function handleBatch(BatchPacket $packet) : bool; - public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool; public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool; diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 9a5b12275..a613d8a41 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -132,11 +132,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ try{ if($packet->buffer !== ""){ $pk = $this->getPacket($packet->buffer); - if($pk !== null){ - $pk->decode(); - assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread!"); - $this->players[$identifier]->handleDataPacket($pk); - } + $this->players[$identifier]->handleDataPacket($pk); } }catch(\Throwable $e){ if(\pocketmine\DEBUG > 1 and isset($pk)){ diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php index 4f952548e..2257655a0 100644 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BatchPacket.php @@ -45,7 +45,32 @@ class BatchPacket extends DataPacket{ } public function handle(NetworkSession $session) : bool{ - return $session->handleBatch($this); + if(strlen($this->payload) < 2){ + throw new \InvalidStateException("Not enough bytes in payload, expected zlib header"); + } + + $str = zlib_decode($this->payload, 1024 * 1024 * 64); //Max 64MB + $len = strlen($str); + + if($len === 0){ + throw new \InvalidStateException("Decoded BatchPacket payload is empty"); + } + + $this->setBuffer($str, 0); + + $network = $session->getServer()->getNetwork(); + while(!$this->feof()){ + $buf = $this->getString(); + $pk = $network->getPacket(ord($buf{0})); + if(!$pk->canBeBatched()){ + throw new \InvalidArgumentException("Received invalid " . get_class($pk) . " inside BatchPacket"); + } + + $pk->setBuffer($buf, 1); + $session->handleDataPacket($pk); + } + + return true; } } \ No newline at end of file