From d542dfc2ce40ebfdf4f4612c38861e996c6b066a Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Fri, 5 Jun 2015 00:19:31 +0200 Subject: [PATCH] Split player into more methods, added extra timings --- src/pocketmine/Player.php | 163 +++++++++++++++++++------------ src/pocketmine/Server.php | 3 + src/pocketmine/event/Timings.php | 9 ++ src/pocketmine/level/Level.php | 6 +- 4 files changed, 115 insertions(+), 66 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6a426a71c..4d62fabfc 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -661,6 +661,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return; } + Timings::$playerChunkSendTimer->startTiming(); + $count = 0; foreach($this->loadQueue as $index => $distance){ if($count >= $this->chunksPerTick){ @@ -674,7 +676,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade ++$count; $this->usedChunks[$index] = false; - $this->level->registerChunkLoader($this, $X, $Z); + $this->level->registerChunkLoader($this, $X, $Z, false); if(!$this->level->populateChunk($X, $Z)){ if($this->spawned and $this->teleportPosition === null){ @@ -689,71 +691,77 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } if($this->chunkLoadCount >= $this->spawnThreshold and $this->spawned === false and $this->teleportPosition === null){ - $this->spawned = true; + $this->doFirstSpawn(); + } - $this->sendSettings(); - $this->sendPotionEffects($this); - $this->sendData($this); - $this->inventory->sendContents($this); - $this->inventory->sendArmorContents($this); + Timings::$playerChunkSendTimer->stopTiming(); + } - $pk = new SetTimePacket(); - $pk->time = $this->level->getTime(); - $pk->started = $this->level->stopTime == false; - $this->dataPacket($pk->setChannel(Network::CHANNEL_PRIORITY)); + protected function doFirstSpawn(){ + $this->spawned = true; - $pos = $this->level->getSafeSpawn($this); + $this->sendSettings(); + $this->sendPotionEffects($this); + $this->sendData($this); + $this->inventory->sendContents($this); + $this->inventory->sendArmorContents($this); - $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos)); + $pk = new SetTimePacket(); + $pk->time = $this->level->getTime(); + $pk->started = $this->level->stopTime == false; + $this->dataPacket($pk->setChannel(Network::CHANNEL_PRIORITY)); - $pos = $ev->getRespawnPosition(); + $pos = $this->level->getSafeSpawn($this); + $this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos)); + + $pos = $ev->getRespawnPosition(); + + $pk = new RespawnPacket(); + $pk->x = $pos->x; + $pk->y = $pos->y; + $pk->z = $pos->z; + $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_CHUNKS)); + + $pk = new PlayStatusPacket(); + $pk->status = PlayStatusPacket::PLAYER_SPAWN; + $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_CHUNKS)); + + $this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, + new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [ + $this->getDisplayName() + ]) + )); + if(strlen(trim($ev->getJoinMessage())) > 0){ + $this->server->broadcastMessage($ev->getJoinMessage()); + } + + $this->noDamageTicks = 60; + + foreach($this->usedChunks as $index => $c){ + Level::getXZ($index, $chunkX, $chunkZ); + foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ + if($entity !== $this and !$entity->closed and $entity->isAlive()){ + $entity->spawnTo($this); + } + } + } + + $this->teleport($pos); + + $this->spawnToAll(); + + if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ + $this->server->getUpdater()->showPlayerUpdate($this); + } + + if($this->getHealth() <= 0){ $pk = new RespawnPacket(); + $pos = $this->getSpawn(); $pk->x = $pos->x; $pk->y = $pos->y; $pk->z = $pos->z; - $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_CHUNKS)); - - $pk = new PlayStatusPacket(); - $pk->status = PlayStatusPacket::PLAYER_SPAWN; - $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_CHUNKS)); - - $this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, - new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [ - $this->getDisplayName() - ]) - )); - if(strlen(trim($ev->getJoinMessage())) > 0){ - $this->server->broadcastMessage($ev->getJoinMessage()); - } - - $this->noDamageTicks = 60; - - foreach($this->usedChunks as $index => $c){ - Level::getXZ($index, $chunkX, $chunkZ); - foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this and !$entity->closed and $entity->isAlive()){ - $entity->spawnTo($this); - } - } - } - - $this->teleport($pos); - - $this->spawnToAll(); - - if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ - $this->server->getUpdater()->showPlayerUpdate($this); - } - - if($this->getHealth() <= 0){ - $pk = new RespawnPacket(); - $pos = $this->getSpawn(); - $pk->x = $pos->x; - $pk->y = $pos->y; - $pk->z = $pos->z; - $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); - } + $this->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); } } @@ -762,6 +770,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return false; } + Timings::$playerChunkOrderTimer->startTiming(); + $this->nextChunkOrderRun = 200; $viewDistance = $this->server->getMemoryManager()->getViewDistance($this->viewDistance); @@ -823,6 +833,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->loadQueue = $newOrder; + + Timings::$playerChunkOrderTimer->stopTiming(); + return true; } @@ -837,8 +850,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($this->connected === false){ return false; } + + Timings::$playerNetworkTimer->startTiming(); $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); if($ev->isCancelled()){ + Timings::$playerNetworkTimer->stopTiming(); return false; } @@ -847,7 +863,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } $this->batchedPackets[$packet->getChannel()][] = clone $packet; - + Timings::$playerNetworkTimer->stopTiming(); return true; } @@ -863,9 +879,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($this->connected === false){ return false; } + Timings::$playerNetworkTimer->startTiming(); $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); if($ev->isCancelled()){ + Timings::$playerNetworkTimer->stopTiming(); return false; } @@ -874,9 +892,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($needACK and $identifier !== null){ $this->needACK[$identifier] = false; + Timings::$playerNetworkTimer->stopTiming(); return $identifier; } + Timings::$playerNetworkTimer->stopTiming(); return true; } @@ -890,8 +910,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($this->connected === false){ return false; } + + Timings::$playerNetworkTimer->startTiming(); $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); if($ev->isCancelled()){ + Timings::$playerNetworkTimer->stopTiming(); return false; } @@ -900,9 +923,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($needACK and $identifier !== null){ $this->needACK[$identifier] = false; + Timings::$playerNetworkTimer->stopTiming(); return $identifier; } + Timings::$playerNetworkTimer->stopTiming(); return true; } @@ -1283,12 +1308,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $revert = true; }else{ if($this->chunk === null or !$this->chunk->isGenerated()){ - $chunk = $this->level->getChunk($newPos->x >> 4, $newPos->z >> 4); - if(!($chunk instanceof FullChunk) or !$chunk->isGenerated()){ + $chunk = $this->level->getChunk($newPos->x >> 4, $newPos->z >> 4, false); + if($chunk === null or !$chunk->isGenerated()){ $revert = true; $this->nextChunkOrderRun = 0; }else{ - if($this->chunk instanceof FullChunk){ + if($this->chunk !== null){ $this->chunk->removeEntity($this); } $this->chunk = $chunk; @@ -1458,6 +1483,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($this->inAirTicks < 100){ $this->setMotion(new Vector3(0, $expectedVelocity, 0)); }elseif($this->kick("Flying is not enabled on this server")){ + $this->timings->stopTiming(); return false; } } @@ -1468,6 +1494,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } + $this->checkTeleportPosition(); + + $this->timings->stopTiming(); + + return true; + } + + public function checkNetwork(){ + if(!$this->isOnline()){ + return; + } + if($this->nextChunkOrderRun-- <= 0 or $this->chunk === null){ $this->orderChunks(); } @@ -1496,11 +1534,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->batchedPackets = []; } - $this->checkTeleportPosition(); - - $this->timings->stopTiming(); - - return true; } public function canInteract(Vector3 $pos, $maxDistance, $maxDiff = 0.5){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 73e3064cf..a5ddc74ee 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1895,6 +1895,7 @@ class Server{ * @param int $channel */ public function batchPackets(array $players, array $packets, $forceSync = false, $channel = 0){ + Timings::$playerNetworkTimer->startTiming(); $str = ""; foreach($packets as $p){ @@ -1921,6 +1922,8 @@ class Server{ }else{ $this->broadcastPacketsCallback(zlib_encode($str, ZLIB_ENCODING_DEFLATE, $this->networkCompressionLevel), $targets, $channel); } + + Timings::$playerNetworkTimer->stopTiming(); } public function broadcastPacketsCallback($data, array $identifiers, $channel = 0){ diff --git a/src/pocketmine/event/Timings.php b/src/pocketmine/event/Timings.php index 545a373a7..9800a9a63 100644 --- a/src/pocketmine/event/Timings.php +++ b/src/pocketmine/event/Timings.php @@ -39,6 +39,12 @@ abstract class Timings{ /** @var TimingsHandler */ public static $playerListTimer; /** @var TimingsHandler */ + public static $playerNetworkTimer; + /** @var TimingsHandler */ + public static $playerChunkOrderTimer; + /** @var TimingsHandler */ + public static $playerChunkSendTimer; + /** @var TimingsHandler */ public static $connectionTimer; /** @var TimingsHandler */ public static $tickablesTimer; @@ -109,6 +115,9 @@ abstract class Timings{ self::$memoryManagerTimer = new TimingsHandler("Memory Manager"); self::$garbageCollectorTimer = new TimingsHandler("Garbage Collector", self::$memoryManagerTimer); self::$playerListTimer = new TimingsHandler("Player List"); + self::$playerNetworkTimer = new TimingsHandler("Player Network"); + self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks"); + self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks"); self::$connectionTimer = new TimingsHandler("Connection Handler"); self::$tickablesTimer = new TimingsHandler("Tickables"); self::$schedulerTimer = new TimingsHandler("Scheduler"); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 987e45a9a..bb9f72656 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -662,6 +662,10 @@ class Level implements ChunkManager, Metadatable{ Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); + foreach($this->players as $player){ + $player->checkNetwork(); + } + $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update @@ -1697,7 +1701,7 @@ class Level implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ foreach($this->getChunkEntities($x, $z) as $ent){ - if($ent !== $entity and ($entity === null or $entity->canCollideWith($ent)) and $ent->boundingBox->intersectsWith($bb)){ + if(($entity === null or ($ent !== $entity and $ent->canCollideWith($entity))) and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } }