diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b2df4f827..0373872fb 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -276,7 +276,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $spawnThreshold; /** @var int */ - protected $chunkLoadCount = 0; + protected $spawnChunkLoadCount = 0; /** @var int */ protected $chunksPerTick; @@ -962,8 +962,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } $this->usedChunks[Level::chunkHash($x, $z)] = true; - $this->chunkLoadCount++; - $this->dataPacket($payload); if($this->spawned){ @@ -974,8 +972,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - if($this->chunkLoadCount >= $this->spawnThreshold and !$this->spawned){ - $this->doFirstSpawn(); + if($this->spawnChunkLoadCount !== -1 and ++$this->spawnChunkLoadCount >= $this->spawnThreshold){ + $this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN); + $this->spawnChunkLoadCount = -1; } } @@ -1013,11 +1012,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ Timings::$playerChunkSendTimer->stopTiming(); } - protected function doFirstSpawn(){ + public function doFirstSpawn(){ + if($this->spawned){ + return; //avoid player spawning twice (this can only happen on 3.x with a custom malicious client) + } $this->spawned = true; - $this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN); - if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); } diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index adecfab3d..44b245b94 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -58,6 +58,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; +use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; @@ -280,4 +281,9 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ return false; //TODO: GUI stuff } + + public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ + $this->player->doFirstSpawn(); + return true; + } }