From 650afe2d94d49ef3b8efebdc4127269596a5d872 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Jun 2017 19:51:53 +0100 Subject: [PATCH 01/10] Added PlayerNetworkSessionAdapter to allow abstraction of NetworkSession base --- src/pocketmine/Player.php | 291 +------ .../network/mcpe/BaseNetworkSession.php | 794 ++++++++++++++++++ .../mcpe/PlayerNetworkSessionAdapter.php | 243 ++++++ 3 files changed, 1049 insertions(+), 279 deletions(-) create mode 100644 src/pocketmine/network/mcpe/BaseNetworkSession.php create mode 100644 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 499d78220..bbd5a395d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -67,7 +67,6 @@ use pocketmine\event\player\PlayerToggleFlightEvent; use pocketmine\event\player\PlayerToggleSneakEvent; use pocketmine\event\player\PlayerToggleSprintEvent; use pocketmine\event\player\PlayerTransferEvent; -use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\TextContainer; use pocketmine\event\Timings; @@ -104,64 +103,39 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\AddEntityPacket; -use pocketmine\network\mcpe\protocol\AddHangingEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemPacket; -use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\network\mcpe\protocol\AddPlayerPacket; +use pocketmine\network\mcpe\PlayerNetworkSessionAdapter; 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\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BossEventPacket; -use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; use pocketmine\network\mcpe\protocol\CommandStepPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetContentPacket; -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; -use pocketmine\network\mcpe\protocol\ExplodePacket; -use pocketmine\network\mcpe\protocol\FullChunkDataPacket; -use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; -use pocketmine\network\mcpe\protocol\HurtArmorPacket; 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\MapInfoRequestPacket; -use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; -use pocketmine\network\mcpe\protocol\MoveEntityPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\EntityFallPacket; use pocketmine\network\mcpe\protocol\PlayerInputPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; -use pocketmine\network\mcpe\protocol\PlaySoundPacket; 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; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; @@ -170,28 +144,17 @@ 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\ServerToClientHandshakePacket; -use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket; -use pocketmine\network\mcpe\protocol\SetDifficultyPacket; -use pocketmine\network\mcpe\protocol\SetEntityDataPacket; -use pocketmine\network\mcpe\protocol\SetEntityLinkPacket; -use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; -use pocketmine\network\mcpe\protocol\SetHealthPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; -use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; -use pocketmine\network\mcpe\protocol\StopSoundPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; 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\network\SourceInterface; use pocketmine\permission\PermissibleBase; @@ -208,7 +171,7 @@ use pocketmine\utils\UUID; /** * Main class that handles networking, recovery, and packet sending to the server part */ -class Player extends Human implements CommandSender, InventoryHolder, ChunkLoader, IPlayer, NetworkSession{ +class Player extends Human implements CommandSender, InventoryHolder, ChunkLoader, IPlayer{ const SURVIVAL = 0; const CREATIVE = 1; @@ -241,6 +204,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade /** @var SourceInterface */ protected $interface; + /** + * @var PlayerNetworkSessionAdapter + * TODO: remove this once player and network are divorced properly + */ + protected $sessionAdapter; + /** @var bool */ public $playedBefore; public $spawned = false; @@ -668,6 +637,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); $this->allowInstaBreak = (bool) $this->server->getProperty("player.anti-cheat.allow-instabreak", false); + + $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this); } /** @@ -1970,10 +1941,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handlePlayStatus(PlayStatusPacket $packet) : bool{ - return false; - } - public function sendPlayStatus(int $status, bool $immediate = false){ $pk = new PlayStatusPacket(); $pk->status = $status; @@ -1984,26 +1951,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } - public function handleServerToClientHandshake(ServerToClientHandshakePacket $packet) : bool{ - return false; - } - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ return false; //TODO } - public function handleDisconnect(DisconnectPacket $packet) : bool{ - return false; - } - - public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool{ - return false; - } - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ switch($packet->status){ case ResourcePackClientResponsePacket::STATUS_REFUSED: @@ -2090,42 +2041,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleSetTime(SetTimePacket $packet) : bool{ - return false; - } - - public function handleStartGame(StartGamePacket $packet) : bool{ - return false; - } - - public function handleAddPlayer(AddPlayerPacket $packet) : bool{ - return false; - } - - public function handleAddEntity(AddEntityPacket $packet) : bool{ - return false; - } - - public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{ - return false; - } - - public function handleAddItemEntity(AddItemEntityPacket $packet) : bool{ - return false; - } - - public function handleAddHangingEntity(AddHangingEntityPacket $packet) : bool{ - return false; - } - - public function handleTakeItemEntity(TakeItemEntityPacket $packet) : bool{ - return false; - } - - public function handleMoveEntity(MoveEntityPacket $packet) : bool{ - return false; - } - public function handleMovePlayer(MovePlayerPacket $packet) : bool{ $newPos = new Vector3($packet->x, $packet->y - $this->baseOffset, $packet->z); @@ -2155,10 +2070,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleRiderJump(RiderJumpPacket $packet) : bool{ - return false; - } - public function handleRemoveBlock(RemoveBlockPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2198,32 +2109,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleUpdateBlock(UpdateBlockPacket $packet) : bool{ - return false; - } - - public function handleAddPainting(AddPaintingPacket $packet) : bool{ - return false; - } - - public function handleExplode(ExplodePacket $packet) : bool{ - return false; - } - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ //TODO: add events so plugins can change this $this->getLevel()->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $packet); return true; } - public function handleLevelEvent(LevelEventPacket $packet) : bool{ - return false; - } - - public function handleBlockEvent(BlockEventPacket $packet) : bool{ - return false; - } - public function handleEntityEvent(EntityEventPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2256,14 +2147,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleMobEffect(MobEffectPacket $packet) : bool{ - return false; - } - - public function handleUpdateAttributes(UpdateAttributesPacket $packet) : bool{ - return false; - } - public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2295,10 +2178,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ - return false; - } - public function handleInteract(InteractPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2809,34 +2688,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleEntityFall(EntityFallPacket $packet) : bool{ - return true; //not used - } - - public function handleHurtArmor(HurtArmorPacket $packet) : bool{ - return false; - } - - public function handleSetEntityData(SetEntityDataPacket $packet) : bool{ - return false; - } - - public function handleSetEntityMotion(SetEntityMotionPacket $packet) : bool{ - return false; - } - - public function handleSetEntityLink(SetEntityLinkPacket $packet) : bool{ - return false; - } - - public function handleSetHealth(SetHealthPacket $packet) : bool{ - return false; - } - - public function handleSetSpawnPosition(SetSpawnPositionPacket $packet) : bool{ - return false; - } - public function handleAnimate(AnimatePacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2855,10 +2706,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleRespawn(RespawnPacket $packet) : bool{ - return false; - } - public function handleDropItem(DropItemPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -2887,14 +2734,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleInventoryAction(InventoryActionPacket $packet) : bool{ - return false; - } - - public function handleContainerOpen(ContainerOpenPacket $packet) : bool{ - return false; - } - public function handleContainerClose(ContainerClosePacket $packet) : bool{ if($this->spawned === false or $packet->windowid === 0){ return true; @@ -2997,18 +2836,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleContainerSetData(ContainerSetDataPacket $packet) : bool{ - return false; - } - - public function handleContainerSetContent(ContainerSetContentPacket $packet) : bool{ - return false; - } - - public function handleCraftingData(CraftingDataPacket $packet) : bool{ - return false; - } - public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -3226,22 +3053,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; //TODO } - public function handleFullChunkData(FullChunkDataPacket $packet) : bool{ - return false; - } - - public function handleSetCommandsEnabled(SetCommandsEnabledPacket $packet) : bool{ - return false; - } - - public function handleSetDifficulty(SetDifficultyPacket $packet) : bool{ - return false; - } - - public function handleChangeDimension(ChangeDimensionPacket $packet) : bool{ - return false; - } - public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ if($packet->gamemode !== $this->gamemode){ //Set this back to default. TODO: handle this properly @@ -3251,18 +3062,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handlePlayerList(PlayerListPacket $packet) : bool{ - return false; - } - public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ return false; //TODO } - public function handleClientboundMapItemData(ClientboundMapItemDataPacket $packet) : bool{ - return false; - } - public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ return false; //TODO } @@ -3273,10 +3076,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleChunkRadiusUpdated(ChunkRadiusUpdatedPacket $packet) : bool{ - return false; - } - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -3306,18 +3105,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleReplaceItemInSlot(ReplaceItemInSlotPacket $packet) : bool{ - return false; - } - - public function handleGameRulesChanged(GameRulesChangedPacket $packet) : bool{ - return false; - } - - public function handleAddItem(AddItemPacket $packet) : bool{ - return false; - } - public function handleBossEvent(BossEventPacket $packet) : bool{ return false; //TODO } @@ -3326,10 +3113,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; //TODO: handle resume } - public function handleAvailableCommands(AvailableCommandsPacket $packet) : bool{ - return false; - } - public function handleCommandStep(CommandStepPacket $packet) : bool{ if($this->spawned === false or !$this->isAlive()){ return true; @@ -3357,18 +3140,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; //TODO } - public function handleUpdateTrade(UpdateTradePacket $packet) : bool{ - return false; - } - - public function handleResourcePackDataInfo(ResourcePackDataInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackChunkData(ResourcePackChunkDataPacket $packet) : bool{ - return false; - } - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ $manager = $this->server->getResourceManager(); $pack = $manager->getPackById($packet->packId); @@ -3388,52 +3159,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return true; } - public function handleTransfer(TransferPacket $packet) : bool{ - return false; - } - - public function handlePlaySound(PlaySoundPacket $packet) : bool{ - return false; - } - - public function handleStopSound(StopSoundPacket $packet) : bool{ - return false; - } - - public function handleSetTitle(SetTitlePacket $packet) : bool{ - return false; - } - /** * Called when a packet is received from the client. This method will call DataPacketReceiveEvent. * * @param DataPacket $packet */ public function handleDataPacket(DataPacket $packet){ - if($this->connected === false){ - return; - } - - //TODO: Remove this hack once InteractPacket spam issue is fixed - if($packet->buffer === "\x21\x04\x00"){ - return; - } - - $timings = Timings::getReceiveDataPacketTimings($packet); - $timings->startTiming(); - - $packet->decode(); - if(!$packet->feof()){ - $remains = substr($packet->buffer, $packet->offset); - $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); - } - - $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet)); - if(!$ev->isCancelled() and !$packet->handle($this)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getName() . ": 0x" . bin2hex($packet->buffer)); - } - - $timings->stopTiming(); + $this->sessionAdapter->handleDataPacket($packet); } /** @@ -3657,6 +3389,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->directDataPacket($pk); } + $this->sessionAdapter->connected = false; $this->connected = false; $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); diff --git a/src/pocketmine/network/mcpe/BaseNetworkSession.php b/src/pocketmine/network/mcpe/BaseNetworkSession.php new file mode 100644 index 000000000..030495d44 --- /dev/null +++ b/src/pocketmine/network/mcpe/BaseNetworkSession.php @@ -0,0 +1,794 @@ +server = $server; + $this->player = $player; + } + + public function getServer(){ + return $this->server; + } + + public function handleDataPacket(DataPacket $packet){ + if($this->connected === false){ + return; + } + + //TODO: Remove this hack once InteractPacket spam issue is fixed + if($packet->buffer === "\x21\x04\x00"){ + return; + } + + $timings = Timings::getReceiveDataPacketTimings($packet); + $timings->startTiming(); + + $packet->decode(); + if(!$packet->feof()){ + $remains = substr($packet->buffer, $packet->offset); + $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); + } + + $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this->player, $packet)); + if(!$ev->isCancelled() and !$packet->handle($this)){ + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->buffer)); + } + + $timings->stopTiming(); + } + + public function handleLogin(LoginPacket $packet) : bool{ + return $this->player->handleLogin($packet); + } + + public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ + return $this->player->handleClientToServerHandshake($packet); + } + + public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ + return $this->player->handleResourcePackClientResponse($packet); + } + + public function handleText(TextPacket $packet) : bool{ + return $this->player->handleText($packet); + } + + public function handleMovePlayer(MovePlayerPacket $packet) : bool{ + return $this->player->handleMovePlayer($packet); + } + + public function handleRemoveBlock(RemoveBlockPacket $packet) : bool{ + return $this->player->handleRemoveBlock($packet); + } + + public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ + return $this->player->handleLevelSoundEvent($packet); + } + + public function handleEntityEvent(EntityEventPacket $packet) : bool{ + return $this->player->handleEntityEvent($packet); + } + + public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ + return $this->player->handleMobEquipment($packet); + } + + public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ + return true; //Not used + } + + public function handleInteract(InteractPacket $packet) : bool{ + return $this->player->handleInteract($packet); + } + + public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ + return $this->player->handleBlockPickRequest($packet); + } + + public function handleUseItem(UseItemPacket $packet) : bool{ + return $this->player->handleUseItem($packet); + } + + public function handlePlayerAction(PlayerActionPacket $packet) : bool{ + return $this->player->handlePlayerAction($packet); + } + + public function handleEntityFall(EntityFallPacket $packet) : bool{ + return true; //Not used + } + + public function handleAnimate(AnimatePacket $packet) : bool{ + return $this->player->handleAnimate($packet); + } + + public function handleDropItem(DropItemPacket $packet) : bool{ + return $this->player->handleDropItem($packet); + } + + public function handleContainerClose(ContainerClosePacket $packet) : bool{ + return $this->player->handleContainerClose($packet); + } + + public function handleContainerSetSlot(ContainerSetSlotPacket $packet) : bool{ + return $this->player->handleContainerSetSlot($packet); + } + + public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ + return $this->player->handleCraftingEvent($packet); + } + + public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ + return $this->player->handleAdventureSettings($packet); + } + + public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ + return $this->player->handleBlockEntityData($packet); + } + + public function handlePlayerInput(PlayerInputPacket $packet) : bool{ + return $this->player->handlePlayerInput($packet); + } + + public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ + return $this->player->handleSetPlayerGameType($packet); + } + + public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ + return $this->player->handleSpawnExperienceOrb($packet); + } + + public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ + return $this->player->handleMapInfoRequest($packet); + } + + public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ + return $this->player->handleRequestChunkRadius($packet); + } + + public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ + return $this->player->handleItemFrameDropItem($packet); + } + + public function handleBossEvent(BossEventPacket $packet) : bool{ + return $this->player->handleBossEvent($packet); + } + + public function handleShowCredits(ShowCreditsPacket $packet) : bool{ + return $this->player->handleShowCredits($packet); + } + + public function handleCommandStep(CommandStepPacket $packet) : bool{ + return $this->player->handleCommandStep($packet); + } + + public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ + return $this->player->handleCommandBlockUpdate($packet); + } + + public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ + return $this->player->handleResourcePackChunkRequest($packet); + } +} \ No newline at end of file From e48599921876f381ae1a8c306ea3fb9e664d7bf9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jul 2017 12:26:37 +0100 Subject: [PATCH 02/10] Just cut the adapter loose instead of needing extra fields for this --- src/pocketmine/Player.php | 6 ++++-- .../network/mcpe/PlayerNetworkSessionAdapter.php | 7 ------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index bbd5a395d..6d00a8f81 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -3165,7 +3165,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade * @param DataPacket $packet */ public function handleDataPacket(DataPacket $packet){ - $this->sessionAdapter->handleDataPacket($packet); + if($this->sessionAdapter !== null){ + $this->sessionAdapter->handleDataPacket($packet); + } } /** @@ -3389,7 +3391,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->directDataPacket($pk); } - $this->sessionAdapter->connected = false; + $this->sessionAdapter = null; $this->connected = false; $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index b6ea50dab..7aa8d3251 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -70,9 +70,6 @@ class PlayerNetworkSessionAdapter extends BaseNetworkSession{ /** @var Player */ private $player; - /** @var bool */ - public $connected = true; - public function __construct(Server $server, Player $player){ $this->server = $server; $this->player = $player; @@ -83,10 +80,6 @@ class PlayerNetworkSessionAdapter extends BaseNetworkSession{ } public function handleDataPacket(DataPacket $packet){ - if($this->connected === false){ - return; - } - //TODO: Remove this hack once InteractPacket spam issue is fixed if($packet->buffer === "\x21\x04\x00"){ return; From 30df0c2418ad71e21df48b93fb9172a54033527c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jul 2017 16:32:39 +0100 Subject: [PATCH 03/10] Refactor a bunch of network-related things for easier auto-generation of protocol stuff --- src/pocketmine/network/Network.php | 211 +---- .../network/mcpe/BaseNetworkSession.php | 794 ------------------ .../network/mcpe/NetworkSession.php | 403 ++++++--- .../mcpe/PlayerNetworkSessionAdapter.php | 6 +- .../network/mcpe/RakLibInterface.php | 3 +- .../mcpe/protocol/AddBehaviorTreePacket.php | 44 + .../network/mcpe/protocol/BatchPacket.php | 3 +- .../network/mcpe/protocol/CameraPacket.php | 44 + .../network/mcpe/protocol/EventPacket.php | 44 + .../network/mcpe/protocol/PacketPool.php | 157 ++++ .../network/mcpe/protocol/ProtocolInfo.php | 4 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 44 + .../mcpe/protocol/ShowStoreOfferPacket.php | 44 + .../mcpe/protocol/SimpleEventPacket.php | 44 + .../protocol/StructureBlockUpdatePacket.php | 44 + .../mcpe/protocol/UpdateEquipPacket.php | 44 + 16 files changed, 818 insertions(+), 1115 deletions(-) delete mode 100644 src/pocketmine/network/mcpe/BaseNetworkSession.php create mode 100644 src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/CameraPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/EventPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/PacketPool.php create mode 100644 src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index a29aa3789..83d3ac6f7 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -26,104 +26,13 @@ declare(strict_types=1); */ namespace pocketmine\network; -use pocketmine\network\mcpe\protocol\AddEntityPacket; -use pocketmine\network\mcpe\protocol\AddHangingEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemPacket; -use pocketmine\network\mcpe\protocol\AddPaintingPacket; -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\BlockPickRequestPacket; -use pocketmine\network\mcpe\protocol\BossEventPacket; -use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; -use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; -use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; -use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; -use pocketmine\network\mcpe\protocol\CommandStepPacket; -use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\ContainerOpenPacket; -use pocketmine\network\mcpe\protocol\ContainerSetContentPacket; -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; -use pocketmine\network\mcpe\protocol\ExplodePacket; -use pocketmine\network\mcpe\protocol\FullChunkDataPacket; -use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; -use pocketmine\network\mcpe\protocol\HurtArmorPacket; -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\MapInfoRequestPacket; -use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; -use pocketmine\network\mcpe\protocol\MoveEntityPacket; -use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\EntityFallPacket; -use pocketmine\network\mcpe\protocol\PlayerInputPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; -use pocketmine\network\mcpe\protocol\PlaySoundPacket; -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; -use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; -use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; -use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; -use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; -use pocketmine\network\mcpe\protocol\RespawnPacket; -use pocketmine\network\mcpe\protocol\RiderJumpPacket; -use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; -use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket; -use pocketmine\network\mcpe\protocol\SetDifficultyPacket; -use pocketmine\network\mcpe\protocol\SetEntityDataPacket; -use pocketmine\network\mcpe\protocol\SetEntityLinkPacket; -use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; -use pocketmine\network\mcpe\protocol\SetHealthPacket; -use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; -use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; -use pocketmine\network\mcpe\protocol\SetTimePacket; -use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\ShowCreditsPacket; -use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; -use pocketmine\network\mcpe\protocol\StartGamePacket; -use pocketmine\network\mcpe\protocol\StopSoundPacket; -use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; -use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\TransferPacket; -use pocketmine\network\mcpe\protocol\UnknownPacket; -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\network\mcpe\protocol\PacketPool; use pocketmine\Server; class Network{ public static $BATCH_THRESHOLD = 512; - /** @var \SplFixedArray */ - private $packetPool; - /** @var Server */ private $server; @@ -139,8 +48,7 @@ class Network{ private $name; public function __construct(Server $server){ - - $this->registerPackets(); + PacketPool::init(); $this->server = $server; @@ -230,33 +138,10 @@ class Network{ } } - /** - * @param int $id 0-255 - * @param DataPacket $class - */ - public function registerPacket($id, $class){ - $this->packetPool[$id] = new $class; - } - public function getServer(){ return $this->server; } - /** - * @param $id - * - * @return DataPacket - */ - public function getPacket($id){ - /** @var DataPacket $class */ - $class = $this->packetPool[$id]; - if($class !== null){ - return clone $class; - } - return new UnknownPacket(); - } - - /** * @param string $address * @param int $port @@ -279,96 +164,4 @@ class Network{ $interface->blockAddress($address, $timeout); } } - - private function registerPackets(){ - $this->packetPool = new \SplFixedArray(256); - - $this->registerPacket(ProtocolInfo::ADD_ENTITY_PACKET, AddEntityPacket::class); - $this->registerPacket(ProtocolInfo::ADD_HANGING_ENTITY_PACKET, AddHangingEntityPacket::class); - $this->registerPacket(ProtocolInfo::ADD_ITEM_ENTITY_PACKET, AddItemEntityPacket::class); - $this->registerPacket(ProtocolInfo::ADD_ITEM_PACKET, AddItemPacket::class); - $this->registerPacket(ProtocolInfo::ADD_PAINTING_PACKET, AddPaintingPacket::class); - $this->registerPacket(ProtocolInfo::ADD_PLAYER_PACKET, AddPlayerPacket::class); - $this->registerPacket(ProtocolInfo::ADVENTURE_SETTINGS_PACKET, AdventureSettingsPacket::class); - $this->registerPacket(ProtocolInfo::ANIMATE_PACKET, AnimatePacket::class); - $this->registerPacket(ProtocolInfo::AVAILABLE_COMMANDS_PACKET, AvailableCommandsPacket::class); - $this->registerPacket(ProtocolInfo::BLOCK_ENTITY_DATA_PACKET, BlockEntityDataPacket::class); - $this->registerPacket(ProtocolInfo::BLOCK_EVENT_PACKET, BlockEventPacket::class); - $this->registerPacket(ProtocolInfo::BLOCK_PICK_REQUEST_PACKET, BlockPickRequestPacket::class); - $this->registerPacket(ProtocolInfo::BOSS_EVENT_PACKET, BossEventPacket::class); - $this->registerPacket(ProtocolInfo::CHANGE_DIMENSION_PACKET, ChangeDimensionPacket::class); - $this->registerPacket(ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket::class); - $this->registerPacket(ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET, ClientboundMapItemDataPacket::class); - $this->registerPacket(ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET, ClientToServerHandshakePacket::class); - $this->registerPacket(ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET, CommandBlockUpdatePacket::class); - $this->registerPacket(ProtocolInfo::COMMAND_STEP_PACKET, CommandStepPacket::class); - $this->registerPacket(ProtocolInfo::CONTAINER_CLOSE_PACKET, ContainerClosePacket::class); - $this->registerPacket(ProtocolInfo::CONTAINER_OPEN_PACKET, ContainerOpenPacket::class); - $this->registerPacket(ProtocolInfo::CONTAINER_SET_CONTENT_PACKET, ContainerSetContentPacket::class); - $this->registerPacket(ProtocolInfo::CONTAINER_SET_DATA_PACKET, ContainerSetDataPacket::class); - $this->registerPacket(ProtocolInfo::CONTAINER_SET_SLOT_PACKET, ContainerSetSlotPacket::class); - $this->registerPacket(ProtocolInfo::CRAFTING_DATA_PACKET, CraftingDataPacket::class); - $this->registerPacket(ProtocolInfo::CRAFTING_EVENT_PACKET, CraftingEventPacket::class); - $this->registerPacket(ProtocolInfo::DISCONNECT_PACKET, DisconnectPacket::class); - $this->registerPacket(ProtocolInfo::DROP_ITEM_PACKET, DropItemPacket::class); - $this->registerPacket(ProtocolInfo::ENTITY_EVENT_PACKET, EntityEventPacket::class); - $this->registerPacket(ProtocolInfo::ENTITY_FALL_PACKET, EntityFallPacket::class); - $this->registerPacket(ProtocolInfo::EXPLODE_PACKET, ExplodePacket::class); - $this->registerPacket(ProtocolInfo::FULL_CHUNK_DATA_PACKET, FullChunkDataPacket::class); - $this->registerPacket(ProtocolInfo::GAME_RULES_CHANGED_PACKET, GameRulesChangedPacket::class); - $this->registerPacket(ProtocolInfo::HURT_ARMOR_PACKET, HurtArmorPacket::class); - $this->registerPacket(ProtocolInfo::INTERACT_PACKET, InteractPacket::class); - $this->registerPacket(ProtocolInfo::INVENTORY_ACTION_PACKET, InventoryActionPacket::class); - $this->registerPacket(ProtocolInfo::ITEM_FRAME_DROP_ITEM_PACKET, ItemFrameDropItemPacket::class); - $this->registerPacket(ProtocolInfo::LEVEL_EVENT_PACKET, LevelEventPacket::class); - $this->registerPacket(ProtocolInfo::LEVEL_SOUND_EVENT_PACKET, LevelSoundEventPacket::class); - $this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class); - $this->registerPacket(ProtocolInfo::MAP_INFO_REQUEST_PACKET, MapInfoRequestPacket::class); - $this->registerPacket(ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET, MobArmorEquipmentPacket::class); - $this->registerPacket(ProtocolInfo::MOB_EFFECT_PACKET, MobEffectPacket::class); - $this->registerPacket(ProtocolInfo::MOB_EQUIPMENT_PACKET, MobEquipmentPacket::class); - $this->registerPacket(ProtocolInfo::MOVE_ENTITY_PACKET, MoveEntityPacket::class); - $this->registerPacket(ProtocolInfo::MOVE_PLAYER_PACKET, MovePlayerPacket::class); - $this->registerPacket(ProtocolInfo::PLAYER_ACTION_PACKET, PlayerActionPacket::class); - $this->registerPacket(ProtocolInfo::PLAYER_INPUT_PACKET, PlayerInputPacket::class); - $this->registerPacket(ProtocolInfo::PLAYER_LIST_PACKET, PlayerListPacket::class); - $this->registerPacket(ProtocolInfo::PLAY_SOUND_PACKET, PlaySoundPacket::class); - $this->registerPacket(ProtocolInfo::PLAY_STATUS_PACKET, PlayStatusPacket::class); - $this->registerPacket(ProtocolInfo::REMOVE_BLOCK_PACKET, RemoveBlockPacket::class); - $this->registerPacket(ProtocolInfo::REMOVE_ENTITY_PACKET, RemoveEntityPacket::class); - $this->registerPacket(ProtocolInfo::REPLACE_ITEM_IN_SLOT_PACKET, ReplaceItemInSlotPacket::class); - $this->registerPacket(ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET, RequestChunkRadiusPacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACKS_INFO_PACKET, ResourcePacksInfoPacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET, ResourcePackChunkDataPacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET, ResourcePackChunkRequestPacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACK_CLIENT_RESPONSE_PACKET, ResourcePackClientResponsePacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET, ResourcePackDataInfoPacket::class); - $this->registerPacket(ProtocolInfo::RESOURCE_PACK_STACK_PACKET, ResourcePackStackPacket::class); - $this->registerPacket(ProtocolInfo::RESPAWN_PACKET, RespawnPacket::class); - $this->registerPacket(ProtocolInfo::RIDER_JUMP_PACKET, RiderJumpPacket::class); - $this->registerPacket(ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET, ServerToClientHandshakePacket::class); - $this->registerPacket(ProtocolInfo::SET_COMMANDS_ENABLED_PACKET, SetCommandsEnabledPacket::class); - $this->registerPacket(ProtocolInfo::SET_DIFFICULTY_PACKET, SetDifficultyPacket::class); - $this->registerPacket(ProtocolInfo::SET_ENTITY_DATA_PACKET, SetEntityDataPacket::class); - $this->registerPacket(ProtocolInfo::SET_ENTITY_LINK_PACKET, SetEntityLinkPacket::class); - $this->registerPacket(ProtocolInfo::SET_ENTITY_MOTION_PACKET, SetEntityMotionPacket::class); - $this->registerPacket(ProtocolInfo::SET_HEALTH_PACKET, SetHealthPacket::class); - $this->registerPacket(ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET, SetPlayerGameTypePacket::class); - $this->registerPacket(ProtocolInfo::SET_SPAWN_POSITION_PACKET, SetSpawnPositionPacket::class); - $this->registerPacket(ProtocolInfo::SET_TIME_PACKET, SetTimePacket::class); - $this->registerPacket(ProtocolInfo::SET_TITLE_PACKET, SetTitlePacket::class); - $this->registerPacket(ProtocolInfo::SHOW_CREDITS_PACKET, ShowCreditsPacket::class); - $this->registerPacket(ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET, SpawnExperienceOrbPacket::class); - $this->registerPacket(ProtocolInfo::START_GAME_PACKET, StartGamePacket::class); - $this->registerPacket(ProtocolInfo::STOP_SOUND_PACKET, StopSoundPacket::class); - $this->registerPacket(ProtocolInfo::TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket::class); - $this->registerPacket(ProtocolInfo::TEXT_PACKET, TextPacket::class); - $this->registerPacket(ProtocolInfo::TRANSFER_PACKET, TransferPacket::class); - $this->registerPacket(ProtocolInfo::UPDATE_ATTRIBUTES_PACKET, UpdateAttributesPacket::class); - $this->registerPacket(ProtocolInfo::UPDATE_BLOCK_PACKET, UpdateBlockPacket::class); - $this->registerPacket(ProtocolInfo::UPDATE_TRADE_PACKET, UpdateTradePacket::class); - $this->registerPacket(ProtocolInfo::USE_ITEM_PACKET, UseItemPacket::class); - - $this->registerPacket(0xfe, BatchPacket::class); - } } diff --git a/src/pocketmine/network/mcpe/BaseNetworkSession.php b/src/pocketmine/network/mcpe/BaseNetworkSession.php deleted file mode 100644 index 030495d44..000000000 --- a/src/pocketmine/network/mcpe/BaseNetworkSession.php +++ /dev/null @@ -1,794 +0,0 @@ -player = $player; } - public function getServer(){ - return $this->server; - } - public function handleDataPacket(DataPacket $packet){ //TODO: Remove this hack once InteractPacket spam issue is fixed if($packet->buffer === "\x21\x04\x00"){ diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index a90cdd0d9..4239eaa39 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -27,6 +27,7 @@ use pocketmine\event\player\PlayerCreationEvent; use pocketmine\network\AdvancedSourceInterface; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Player; @@ -236,7 +237,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ private function getPacket($buffer){ $pid = ord($buffer{0}); - if(($data = $this->network->getPacket($pid)) === null){ + if(($data = PacketPool::getPacketById($pid)) === null){ return null; } $data->setBuffer($buffer, 1); diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php new file mode 100644 index 000000000..af461e714 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class AddBehaviorTreePacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleAddBehaviorTree($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php index 21962fc05..a2095c050 100644 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BatchPacket.php @@ -91,10 +91,9 @@ class BatchPacket extends DataPacket{ $this->setBuffer($str, 0); - $network = $session->getServer()->getNetwork(); while(!$this->feof()){ $buf = $this->getString(); - $pk = $network->getPacket(ord($buf{0})); + $pk = PacketPool::getPacketById(ord($buf{0})); if(!$pk->canBeBatched()){ throw new \InvalidArgumentException("Received invalid " . get_class($pk) . " inside BatchPacket"); diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php new file mode 100644 index 000000000..2f697bb39 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class CameraPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleCamera($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/pocketmine/network/mcpe/protocol/EventPacket.php new file mode 100644 index 000000000..984c45680 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/EventPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class EventPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::EVENT_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleEvent($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php new file mode 100644 index 000000000..39cbf1877 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -0,0 +1,157 @@ + */ + protected static $pool = null; + + public static function init(){ + static::$pool = new \SplFixedArray(256); + + //Normal packets + static::registerPacket(new LoginPacket()); + static::registerPacket(new PlayStatusPacket()); + static::registerPacket(new ServerToClientHandshakePacket()); + static::registerPacket(new ClientToServerHandshakePacket()); + static::registerPacket(new DisconnectPacket()); + static::registerPacket(new ResourcePacksInfoPacket()); + static::registerPacket(new ResourcePackStackPacket()); + static::registerPacket(new ResourcePackClientResponsePacket()); + static::registerPacket(new TextPacket()); + static::registerPacket(new SetTimePacket()); + static::registerPacket(new StartGamePacket()); + static::registerPacket(new AddPlayerPacket()); + static::registerPacket(new AddEntityPacket()); + static::registerPacket(new RemoveEntityPacket()); + static::registerPacket(new AddItemEntityPacket()); + static::registerPacket(new AddHangingEntityPacket()); + static::registerPacket(new TakeItemEntityPacket()); + static::registerPacket(new MoveEntityPacket()); + static::registerPacket(new MovePlayerPacket()); + static::registerPacket(new RiderJumpPacket()); + static::registerPacket(new RemoveBlockPacket()); + static::registerPacket(new UpdateBlockPacket()); + static::registerPacket(new AddPaintingPacket()); + static::registerPacket(new ExplodePacket()); + static::registerPacket(new LevelSoundEventPacket()); + static::registerPacket(new LevelEventPacket()); + static::registerPacket(new BlockEventPacket()); + static::registerPacket(new EntityEventPacket()); + static::registerPacket(new MobEffectPacket()); + static::registerPacket(new UpdateAttributesPacket()); + static::registerPacket(new MobEquipmentPacket()); + static::registerPacket(new MobArmorEquipmentPacket()); + static::registerPacket(new InteractPacket()); + static::registerPacket(new BlockPickRequestPacket()); + static::registerPacket(new UseItemPacket()); + static::registerPacket(new PlayerActionPacket()); + static::registerPacket(new EntityFallPacket()); + static::registerPacket(new HurtArmorPacket()); + static::registerPacket(new SetEntityDataPacket()); + static::registerPacket(new SetEntityMotionPacket()); + static::registerPacket(new SetEntityLinkPacket()); + static::registerPacket(new SetHealthPacket()); + static::registerPacket(new SetSpawnPositionPacket()); + static::registerPacket(new AnimatePacket()); + static::registerPacket(new RespawnPacket()); + static::registerPacket(new DropItemPacket()); + static::registerPacket(new InventoryActionPacket()); + static::registerPacket(new ContainerOpenPacket()); + static::registerPacket(new ContainerClosePacket()); + static::registerPacket(new ContainerSetSlotPacket()); + static::registerPacket(new ContainerSetDataPacket()); + static::registerPacket(new ContainerSetContentPacket()); + static::registerPacket(new CraftingDataPacket()); + static::registerPacket(new CraftingEventPacket()); + static::registerPacket(new AdventureSettingsPacket()); + static::registerPacket(new BlockEntityDataPacket()); + static::registerPacket(new PlayerInputPacket()); + static::registerPacket(new FullChunkDataPacket()); + static::registerPacket(new SetCommandsEnabledPacket()); + static::registerPacket(new SetDifficultyPacket()); + static::registerPacket(new ChangeDimensionPacket()); + static::registerPacket(new SetPlayerGameTypePacket()); + static::registerPacket(new PlayerListPacket()); + static::registerPacket(new SimpleEventPacket()); + static::registerPacket(new EventPacket()); + static::registerPacket(new SpawnExperienceOrbPacket()); + static::registerPacket(new ClientboundMapItemDataPacket()); + static::registerPacket(new MapInfoRequestPacket()); + static::registerPacket(new RequestChunkRadiusPacket()); + static::registerPacket(new ChunkRadiusUpdatedPacket()); + static::registerPacket(new ItemFrameDropItemPacket()); + static::registerPacket(new ReplaceItemInSlotPacket()); + static::registerPacket(new GameRulesChangedPacket()); + static::registerPacket(new CameraPacket()); + static::registerPacket(new AddItemPacket()); + static::registerPacket(new BossEventPacket()); + static::registerPacket(new ShowCreditsPacket()); + static::registerPacket(new AvailableCommandsPacket()); + static::registerPacket(new CommandStepPacket()); + static::registerPacket(new CommandBlockUpdatePacket()); + static::registerPacket(new UpdateTradePacket()); + static::registerPacket(new UpdateEquipPacket()); + static::registerPacket(new ResourcePackDataInfoPacket()); + static::registerPacket(new ResourcePackChunkDataPacket()); + static::registerPacket(new ResourcePackChunkRequestPacket()); + static::registerPacket(new TransferPacket()); + static::registerPacket(new PlaySoundPacket()); + static::registerPacket(new StopSoundPacket()); + static::registerPacket(new SetTitlePacket()); + static::registerPacket(new AddBehaviorTreePacket()); + static::registerPacket(new StructureBlockUpdatePacket()); + static::registerPacket(new ShowStoreOfferPacket()); + static::registerPacket(new PurchaseReceiptPacket()); + + static::registerPacket(new BatchPacket()); + } + + /** + * @param DataPacket $packet + */ + public static function registerPacket(DataPacket $packet){ + static::$pool[$packet->pid()] = clone $packet; + } + + /** + * @param int $pid + * @return DataPacket + */ + public static function getPacketById(int $pid) : DataPacket{ + return static::$pool[$pid] ?? new UnknownPacket(); + } + + /** + * @param string $buffer + * @return DataPacket + */ + public static function getPacket(string $buffer) : DataPacket{ + $pk = static::getPacketById(ord($buffer{0})); + $pk->setBuffer($buffer); + + return $pk; + } + +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index e399bb864..d49946a51 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -43,11 +43,11 @@ interface ProtocolInfo{ /** * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - const MINECRAFT_VERSION = 'v1.1.0.55'; + const MINECRAFT_VERSION = 'v1.1.3.1 beta'; /** * Version number sent to clients in ping responses. */ - const MINECRAFT_VERSION_NETWORK = '1.1.0.55'; + const MINECRAFT_VERSION_NETWORK = '1.1.3.1'; const LOGIN_PACKET = 0x01; const PLAY_STATUS_PACKET = 0x02; diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php new file mode 100644 index 000000000..7da5afa0e --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class PurchaseReceiptPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::PURCHASE_RECEIPT_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handlePurchaseReceipt($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php new file mode 100644 index 000000000..b44e1d352 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class ShowStoreOfferPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleShowStoreOffer($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php new file mode 100644 index 000000000..4337a8a1e --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class SimpleEventPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleSimpleEvent($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php new file mode 100644 index 000000000..f6971700e --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class StructureBlockUpdatePacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleStructureBlockUpdate($this); + } +} \ No newline at end of file diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php new file mode 100644 index 000000000..16b8239b6 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -0,0 +1,44 @@ + + +use pocketmine\network\mcpe\NetworkSession; + +class UpdateEquipPacket extends DataPacket{ + const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; + + public function decodePayload(){ + //TODO + } + + public function encodePayload(){ + //TODO + } + + public function handle(NetworkSession $session) : bool{ + return $session->handleUpdateEquip($this); + } +} \ No newline at end of file From 4731bf0a16f73a7184e1dfedbb9504f86cb946fc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jul 2017 16:36:04 +0100 Subject: [PATCH 04/10] Fix autogenerated version numbers (didn't mean to commit this) I'm working with a beta version >_> --- src/pocketmine/network/mcpe/protocol/ProtocolInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php index d49946a51..e399bb864 100644 --- a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php +++ b/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php @@ -43,11 +43,11 @@ interface ProtocolInfo{ /** * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. */ - const MINECRAFT_VERSION = 'v1.1.3.1 beta'; + const MINECRAFT_VERSION = 'v1.1.0.55'; /** * Version number sent to clients in ping responses. */ - const MINECRAFT_VERSION_NETWORK = '1.1.3.1'; + const MINECRAFT_VERSION_NETWORK = '1.1.0.55'; const LOGIN_PACKET = 0x01; const PLAY_STATUS_PACKET = 0x02; From a5c6c8b9731e799a4e12a6a4a918c1d0093a645e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jul 2017 19:30:26 +0100 Subject: [PATCH 05/10] Added some fields to new packets gave up on EventPacket because it's a mess, and StructureBlockUpdate is a job all by itself --- .../mcpe/protocol/AddBehaviorTreePacket.php | 7 +++-- .../network/mcpe/protocol/CameraPacket.php | 11 ++++++-- .../network/mcpe/protocol/EventPacket.php | 27 +++++++++++++++++-- .../mcpe/protocol/PurchaseReceiptPacket.php | 13 +++++++-- .../mcpe/protocol/ShowStoreOfferPacket.php | 6 +++-- .../mcpe/protocol/SimpleEventPacket.php | 6 +++-- .../mcpe/protocol/UpdateEquipPacket.php | 18 +++++++++++-- 7 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php index af461e714..56a5e0fc5 100644 --- a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -30,12 +30,15 @@ use pocketmine\network\mcpe\NetworkSession; class AddBehaviorTreePacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; + /** @var string */ + public $unknownString1; + public function decodePayload(){ - //TODO + $this->unknownString1 = $this->getString(); } public function encodePayload(){ - //TODO + $this->putString($this->unknownString1); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php index 2f697bb39..ecc62f862 100644 --- a/src/pocketmine/network/mcpe/protocol/CameraPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -30,12 +30,19 @@ use pocketmine\network\mcpe\NetworkSession; class CameraPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; + /** @var int */ + public $cameraUniqueId; + /** @var int */ + public $playerUniqueId; + public function decodePayload(){ - //TODO + $this->cameraUniqueId = $this->getEntityUniqueId(); + $this->playerUniqueId = $this->getEntityUniqueId(); } public function encodePayload(){ - //TODO + $this->putEntityUniqueId($this->cameraUniqueId); + $this->putEntityUniqueId($this->playerUniqueId); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/pocketmine/network/mcpe/protocol/EventPacket.php index 984c45680..f76b89e9a 100644 --- a/src/pocketmine/network/mcpe/protocol/EventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EventPacket.php @@ -30,12 +30,35 @@ use pocketmine\network\mcpe\NetworkSession; class EventPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::EVENT_PACKET; + const TYPE_ACHIEVEMENT_AWARDED = 0; + const TYPE_ENTITY_INTERACT = 1; + const TYPE_PORTAL_BUILT = 2; + const TYPE_PORTAL_USED = 3; + const TYPE_MOB_KILLED = 4; + const TYPE_CAULDRON_USED = 5; + const TYPE_PLAYER_DEATH = 6; + const TYPE_BOSS_KILLED = 7; + const TYPE_AGENT_COMMAND = 8; + const TYPE_AGENT_CREATED = 9; + + public $playerRuntimeId; + public $eventData; + public $type; + public function decodePayload(){ - //TODO + $this->playerRuntimeId = $this->getEntityRuntimeId(); + $this->eventData = $this->getVarInt(); + $this->type = $this->getByte(); + + //TODO: nice confusing mess } public function encodePayload(){ - //TODO + $this->putEntityRuntimeId($this->playerRuntimeId); + $this->putVarInt($this->eventData); + $this->putByte($this->type); + + //TODO: also nice confusing mess } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php index 7da5afa0e..d1926475b 100644 --- a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -30,12 +30,21 @@ use pocketmine\network\mcpe\NetworkSession; class PurchaseReceiptPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::PURCHASE_RECEIPT_PACKET; + /** @var string[] */ + public $entries = []; + public function decodePayload(){ - //TODO + $count = $this->getUnsignedVarInt(); + for($i = 0; $i < $count; ++$i){ + $this->entries[] = $this->getString(); + } } public function encodePayload(){ - //TODO + $this->putUnsignedVarInt(count($this->entries)); + foreach($this->entries as $entry){ + $this->putString($entry); + } } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php index b44e1d352..ab079ce30 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -30,12 +30,14 @@ use pocketmine\network\mcpe\NetworkSession; class ShowStoreOfferPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; + public $offerId; + public function decodePayload(){ - //TODO + $this->offerId = $this->getString(); } public function encodePayload(){ - //TODO + $this->putString($this->offerId); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php index 4337a8a1e..354008f2a 100644 --- a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php @@ -30,12 +30,14 @@ use pocketmine\network\mcpe\NetworkSession; class SimpleEventPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; + public $unknownShort1; + public function decodePayload(){ - //TODO + $this->unknownShort1 = $this->getLShort(); } public function encodePayload(){ - //TODO + $this->putLShort($this->unknownShort1); } public function handle(NetworkSession $session) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php index 16b8239b6..7f3c9bbd7 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -30,12 +30,26 @@ use pocketmine\network\mcpe\NetworkSession; class UpdateEquipPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; + public $windowId; + public $windowType; + public $unknownVarint; //TODO: find out what this is (vanilla always sends 0) + public $entityUniqueId; + public $namedtag; + public function decodePayload(){ - //TODO + $this->windowId = $this->getByte(); + $this->windowType = $this->getByte(); + $this->unknownVarint = $this->getVarInt(); + $this->entityUniqueId = $this->getEntityUniqueId(); + $this->namedtag = $this->get(true); } public function encodePayload(){ - //TODO + $this->putByte($this->windowId); + $this->putByte($this->windowType); + $this->putVarInt($this->unknownVarint); + $this->putEntityUniqueId($this->entityUniqueId); + $this->put($this->namedtag); } public function handle(NetworkSession $session) : bool{ From 5283975f20af89d0eb5ce02163509c6387eeb5a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jul 2017 20:01:46 +0100 Subject: [PATCH 06/10] Move inventory ID constants to their own interface ContainerSetContentPacket will be removed in 1.2, and these aren't specific to ContainerSetContentPacket anyway. --- src/pocketmine/Player.php | 7 ++-- src/pocketmine/inventory/PlayerInventory.php | 9 +++-- .../protocol/ContainerSetContentPacket.php | 10 +---- .../mcpe/protocol/types/ContainerIds.php | 38 +++++++++++++++++++ 4 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/types/ContainerIds.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6d00a8f81..f3b8e0dd1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -153,6 +153,7 @@ use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; +use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\protocol\UseItemPacket; @@ -2761,21 +2762,21 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } switch($packet->windowid){ - case ContainerSetContentPacket::SPECIAL_INVENTORY: //Normal inventory change + case ContainerIds::INVENTORY: //Normal inventory change if($packet->slot >= $this->inventory->getSize()){ return false; } $transaction = new BaseTransaction($this->inventory, $packet->slot, $this->inventory->getItem($packet->slot), $packet->item); break; - case ContainerSetContentPacket::SPECIAL_ARMOR: //Armour change + case ContainerIds::ARMOR: //Armour change if($packet->slot >= 4){ return false; } $transaction = new BaseTransaction($this->inventory, $packet->slot + $this->inventory->getSize(), $this->inventory->getArmorItem($packet->slot), $packet->item); break; - case ContainerSetContentPacket::SPECIAL_HOTBAR: //Hotbar link update + case ContainerIds::HOTBAR: //Hotbar link update //hotbarSlot 0-8, slot 9-44 $this->inventory->setHotbarSlotIndex($packet->hotbarSlot, $packet->slot - 9); return true; diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index b7b5bf41a..994cfd5f7 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -32,6 +32,7 @@ use pocketmine\network\mcpe\protocol\ContainerSetContentPacket; use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; +use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\Player; use pocketmine\Server; @@ -238,7 +239,7 @@ class PlayerInventory extends BaseInventory{ $pk->item = $item; $pk->inventorySlot = $this->getHeldItemSlot(); $pk->hotbarSlot = $this->getHeldItemIndex(); - $pk->windowId = ContainerSetContentPacket::SPECIAL_INVENTORY; + $pk->windowId = ContainerIds::INVENTORY; if(!is_array($target)){ $target->dataPacket($pk); @@ -424,7 +425,7 @@ class PlayerInventory extends BaseInventory{ foreach($target as $player){ if($player === $this->getHolder()){ $pk2 = new ContainerSetContentPacket(); - $pk2->windowid = ContainerSetContentPacket::SPECIAL_ARMOR; + $pk2->windowid = ContainerIds::ARMOR; $pk2->slots = $armor; $pk2->targetEid = $player->getId(); $player->dataPacket($pk2); @@ -473,7 +474,7 @@ class PlayerInventory extends BaseInventory{ if($player === $this->getHolder()){ /** @var Player $player */ $pk2 = new ContainerSetSlotPacket(); - $pk2->windowid = ContainerSetContentPacket::SPECIAL_ARMOR; + $pk2->windowid = ContainerIds::ARMOR; $pk2->slot = $index - $this->getSize(); $pk2->item = $this->getItem($index); $player->dataPacket($pk2); @@ -523,7 +524,7 @@ class PlayerInventory extends BaseInventory{ public function sendCreativeContents(){ $pk = new ContainerSetContentPacket(); - $pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE; + $pk->windowid = ContainerIds::CREATIVE; if($this->getHolder()->getGamemode() === Player::CREATIVE){ foreach(Item::getCreativeItems() as $i => $item){ $pk->slots[$i] = clone $item; diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetContentPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetContentPacket.php index 62723d4f3..bb47539b7 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetContentPacket.php @@ -27,17 +27,11 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\types\ContainerIds; class ContainerSetContentPacket extends DataPacket{ const NETWORK_ID = ProtocolInfo::CONTAINER_SET_CONTENT_PACKET; - const SPECIAL_INVENTORY = 0; - const SPECIAL_OFFHAND = 0x77; - const SPECIAL_ARMOR = 0x78; - const SPECIAL_CREATIVE = 0x79; - const SPECIAL_HOTBAR = 0x7a; - const SPECIAL_FIXED_INVENTORY = 0x7b; - public $windowid; public $targetEid; public $slots = []; @@ -70,7 +64,7 @@ class ContainerSetContentPacket extends DataPacket{ foreach($this->slots as $slot){ $this->putSlot($slot); } - if($this->windowid === self::SPECIAL_INVENTORY and count($this->hotbar) > 0){ + if($this->windowid === ContainerIds::INVENTORY and count($this->hotbar) > 0){ $this->putUnsignedVarInt(count($this->hotbar)); foreach($this->hotbar as $slot){ $this->putVarInt($slot); diff --git a/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php b/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php new file mode 100644 index 000000000..640dea519 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php @@ -0,0 +1,38 @@ + Date: Thu, 13 Jul 2017 12:04:47 +0100 Subject: [PATCH 07/10] Improved batch handling --- src/pocketmine/Server.php | 8 +-- .../level/format/io/ChunkRequestTask.php | 3 +- .../network/CompressBatchedTask.php | 11 ++-- .../network/mcpe/protocol/BatchPacket.php | 55 +++++++++++-------- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 1f920e36b..0c9a7e96e 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -257,6 +257,7 @@ class Server{ /** @var Player[] */ private $playerList = []; + /** @var string[] */ private $identifiers = []; /** @var Level[] */ @@ -1846,17 +1847,16 @@ class Server{ } if(Network::$BATCH_THRESHOLD >= 0 and strlen($pk->payload) >= Network::$BATCH_THRESHOLD){ - $compressionLevel = $this->networkCompressionLevel; + $pk->setCompressionLevel($this->networkCompressionLevel); }else{ - $compressionLevel = 0; //Do not compress packets under the threshold + $pk->setCompressionLevel(0); //Do not compress packets under the threshold $forceSync = true; } if(!$forceSync and !$immediate and $this->networkCompressionAsync){ - $task = new CompressBatchedTask($pk, $targets, $compressionLevel); + $task = new CompressBatchedTask($pk, $targets); $this->getScheduler()->scheduleAsyncTask($task); }else{ - $pk->compress($compressionLevel); $this->broadcastPacketsCallback($pk, $targets, $immediate); } } diff --git a/src/pocketmine/level/format/io/ChunkRequestTask.php b/src/pocketmine/level/format/io/ChunkRequestTask.php index 75944af4d..01261ddd3 100644 --- a/src/pocketmine/level/format/io/ChunkRequestTask.php +++ b/src/pocketmine/level/format/io/ChunkRequestTask.php @@ -75,7 +75,7 @@ class ChunkRequestTask extends AsyncTask{ $batch = new BatchPacket(); $batch->addPacket($pk); - $batch->compress($this->compressionLevel); + $batch->setCompressionLevel($this->compressionLevel); $batch->encode(); $this->setResult($batch->buffer, false); @@ -87,7 +87,6 @@ class ChunkRequestTask extends AsyncTask{ if($this->hasResult()){ $batch = new BatchPacket($this->getResult()); assert(strlen($batch->buffer) > 0); - $batch->compressed = true; $batch->isEncoded = true; $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $batch); }else{ diff --git a/src/pocketmine/network/CompressBatchedTask.php b/src/pocketmine/network/CompressBatchedTask.php index afecfa2bd..a70cd5531 100644 --- a/src/pocketmine/network/CompressBatchedTask.php +++ b/src/pocketmine/network/CompressBatchedTask.php @@ -33,10 +33,14 @@ class CompressBatchedTask extends AsyncTask{ public $data; public $targets; - public function __construct(BatchPacket $batch, array $targets, $level = 7){ + /** + * @param BatchPacket $batch + * @param string[] $targets + */ + public function __construct(BatchPacket $batch, array $targets){ $this->data = $batch->payload; $this->targets = serialize($targets); - $this->level = $level; + $this->level = $batch->getCompressionLevel(); } public function onRun(){ @@ -44,7 +48,7 @@ class CompressBatchedTask extends AsyncTask{ $batch->payload = $this->data; $this->data = null; - $batch->compress($this->level); + $batch->setCompressionLevel($this->level); $batch->encode(); $this->setResult($batch->buffer, false); @@ -53,7 +57,6 @@ class CompressBatchedTask extends AsyncTask{ public function onCompletion(Server $server){ $pk = new BatchPacket($this->getResult()); $pk->isEncoded = true; - $pk->compressed = true; $server->broadcastPacketsCallback($pk, unserialize($this->targets)); } } diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php index a2095c050..af4ed8ab5 100644 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BatchPacket.php @@ -29,13 +29,17 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; #ifndef COMPILE use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; + #endif class BatchPacket extends DataPacket{ const NETWORK_ID = 0xfe; - public $payload; - public $compressed = false; + /** @var string */ + public $payload = ""; + /** @var int */ + protected $compressionLevel = 7; public function canBeBatched() : bool{ return false; @@ -46,12 +50,16 @@ class BatchPacket extends DataPacket{ } public function decodePayload(){ - $this->payload = $this->getRemaining(); + $data = $this->getRemaining(); + try{ + $this->payload = zlib_decode($data, 1024 * 1024 * 64); //Max 64MB + }catch(\ErrorException $e){ //zlib decode error + $this->payload = ""; + } } public function encodePayload(){ - assert($this->compressed); - $this->put($this->payload); + $this->put(zlib_encode($this->payload, ZLIB_ENCODING_DEFLATE, $this->compressionLevel)); } /** @@ -68,31 +76,30 @@ class BatchPacket extends DataPacket{ $this->payload .= Binary::writeUnsignedVarInt(strlen($packet->buffer)) . $packet->buffer; } - public function compress(int $level = 7){ - assert(!$this->compressed); - $this->payload = zlib_encode($this->payload, ZLIB_ENCODING_DEFLATE, $level); - $this->compressed = true; + /** + * @return \Generator + */ + public function getPackets(){ + $stream = new BinaryStream($this->payload); + while(!$stream->feof()){ + yield $stream->getString(); + } + } + + public function getCompressionLevel() : int{ + return $this->compressionLevel; + } + + public function setCompressionLevel(int $level){ + $this->compressionLevel = $level; } public function handle(NetworkSession $session) : bool{ - if(strlen($this->payload) < 2){ + if($this->payload === ""){ return false; } - try{ - $str = zlib_decode($this->payload, 1024 * 1024 * 64); //Max 64MB - }catch(\ErrorException $e){ - return false; - } - - if(strlen($str) === 0){ - throw new \InvalidStateException("Decoded BatchPacket payload is empty"); - } - - $this->setBuffer($str, 0); - - while(!$this->feof()){ - $buf = $this->getString(); + foreach($this->getPackets() as $buf){ $pk = PacketPool::getPacketById(ord($buf{0})); if(!$pk->canBeBatched()){ From 6341d3a0dc4cc260c7470a82aab558fe64be4ff1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jul 2017 12:09:03 +0100 Subject: [PATCH 08/10] don't break the preprocessor --- src/pocketmine/network/mcpe/protocol/BatchPacket.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php index af4ed8ab5..5ffa247cb 100644 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BatchPacket.php @@ -29,9 +29,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\NetworkSession; #ifndef COMPILE use pocketmine\utils\Binary; -use pocketmine\utils\BinaryStream; - #endif +use pocketmine\utils\BinaryStream; class BatchPacket extends DataPacket{ const NETWORK_ID = 0xfe; From 3a214b7ce6fb434d4fa418e8f23f10da02f08141 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jul 2017 12:21:26 +0100 Subject: [PATCH 09/10] Cleaned up isEncoded mess --- src/pocketmine/Server.php | 2 -- src/pocketmine/inventory/CraftingManager.php | 1 - src/pocketmine/inventory/PlayerInventory.php | 2 -- src/pocketmine/network/mcpe/RakLibInterface.php | 1 - src/pocketmine/network/mcpe/protocol/DataPacket.php | 1 + 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 0c9a7e96e..99f8de969 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1817,7 +1817,6 @@ class Server{ */ public function broadcastPacket(array $players, DataPacket $packet){ $packet->encode(); - $packet->isEncoded = true; $this->batchPackets($players, [$packet], false); } @@ -1867,7 +1866,6 @@ class Server{ public function broadcastPacketsCallback(BatchPacket $pk, array $identifiers, bool $immediate = false){ if(!$pk->isEncoded){ $pk->encode(); - $pk->isEncoded = true; } if($immediate){ diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index aca85258b..208bdcdcf 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -112,7 +112,6 @@ class CraftingManager{ } $pk->encode(); - $pk->isEncoded = true; $this->craftingDataCache = $pk; Timings::$craftingDataCacheRebuildTimer->stopTiming(); diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 994cfd5f7..52ba0da8d 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -420,7 +420,6 @@ class PlayerInventory extends BaseInventory{ $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; $pk->encode(); - $pk->isEncoded = true; foreach($target as $player){ if($player === $this->getHolder()){ @@ -468,7 +467,6 @@ class PlayerInventory extends BaseInventory{ $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; $pk->encode(); - $pk->isEncoded = true; foreach($target as $player){ if($player === $this->getHolder()){ diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 4239eaa39..20882e28e 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -200,7 +200,6 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ $identifier = $this->identifiers[$h]; if(!$packet->isEncoded){ $packet->encode(); - $packet->isEncoded = true; } if($packet instanceof BatchPacket){ diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index d251f1d7a..d7ec82b6c 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -70,6 +70,7 @@ abstract class DataPacket extends BinaryStream{ public function encode(){ $this->reset(); $this->encodePayload(); + $this->isEncoded = true; } /** From 6a191b506933cc32c54db47784cf854fb02db0c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jul 2017 19:59:01 +0100 Subject: [PATCH 10/10] Remove useless condition --- src/pocketmine/network/mcpe/RakLibInterface.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 20882e28e..882819992 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -143,9 +143,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ $logger->debug("Packet " . (isset($pk) ? get_class($pk) : "unknown") . " 0x" . bin2hex($packet->buffer)); $logger->logException($e); - if(isset($this->players[$identifier])){ - $this->interface->blockAddress($this->players[$identifier]->getAddress(), 5); - } + $this->interface->blockAddress($this->players[$identifier]->getAddress(), 5); } } }