diff --git a/src/Server.php b/src/Server.php index 5b53b3819..71e43b155 100644 --- a/src/Server.php +++ b/src/Server.php @@ -91,7 +91,6 @@ use pocketmine\scheduler\AsyncPool; use pocketmine\snooze\SleeperHandler; use pocketmine\stats\SendUsageTask; use pocketmine\timings\Timings; -use pocketmine\timings\TimingsAwareSleeperHandler; use pocketmine\timings\TimingsHandler; use pocketmine\updater\UpdateChecker; use pocketmine\utils\AssumptionFailedError; @@ -206,7 +205,7 @@ class Server{ private static ?Server $instance = null; - private SleeperHandler $tickSleeper; + private TimeTrackingSleeperHandler $tickSleeper; private BanList $banByName; @@ -773,7 +772,7 @@ class Server{ $this->useAverage = array_fill(0, self::TARGET_TICKS_PER_SECOND, 0); Timings::init(); - $this->tickSleeper = new TimingsAwareSleeperHandler(Timings::$serverInterrupts); + $this->tickSleeper = new TimeTrackingSleeperHandler(Timings::$serverInterrupts); $this->signalHandler = new SignalHandler(function() : void{ $this->logger->info("Received signal interrupt, stopping the server"); @@ -1858,14 +1857,16 @@ class Server{ Timings::$serverTick->stopTiming(); $now = microtime(true); - $this->currentTPS = min(self::TARGET_TICKS_PER_SECOND, 1 / max(0.001, $now - $tickTime)); - $this->currentUse = min(1, ($now - $tickTime) / self::TARGET_SECONDS_PER_TICK); + $totalTickTimeSeconds = $now - $tickTime + ($this->tickSleeper->getNotificationProcessingTime() / 1_000_000_000); + $this->currentTPS = min(self::TARGET_TICKS_PER_SECOND, 1 / max(0.001, $totalTickTimeSeconds)); + $this->currentUse = min(1, $totalTickTimeSeconds / self::TARGET_SECONDS_PER_TICK); TimingsHandler::tick($this->currentTPS <= $this->profilingTickRate); $idx = $this->tickCounter % self::TARGET_TICKS_PER_SECOND; $this->tickAverage[$idx] = $this->currentTPS; $this->useAverage[$idx] = $this->currentUse; + $this->tickSleeper->resetNotificationProcessingTime(); if(($this->nextTick - $tickTime) < -1){ $this->nextTick = $tickTime; diff --git a/src/timings/TimingsAwareSleeperHandler.php b/src/TimeTrackingSleeperHandler.php similarity index 62% rename from src/timings/TimingsAwareSleeperHandler.php rename to src/TimeTrackingSleeperHandler.php index 80a1a0c57..970d85ce0 100644 --- a/src/timings/TimingsAwareSleeperHandler.php +++ b/src/TimeTrackingSleeperHandler.php @@ -21,14 +21,19 @@ declare(strict_types=1); -namespace pocketmine\timings; +namespace pocketmine; use pocketmine\snooze\SleeperHandler; +use pocketmine\timings\TimingsHandler; +use function hrtime; /** * Custom Snooze sleeper handler which captures notification processing time. + * @internal */ -final class TimingsAwareSleeperHandler extends SleeperHandler{ +final class TimeTrackingSleeperHandler extends SleeperHandler{ + + private int $notificationProcessingTimeNs = 0; public function __construct( private TimingsHandler $timings @@ -36,11 +41,23 @@ final class TimingsAwareSleeperHandler extends SleeperHandler{ parent::__construct(); } + /** + * Returns the time in nanoseconds spent processing notifications since the last reset. + */ + public function getNotificationProcessingTime() : int{ return $this->notificationProcessingTimeNs; } + + /** + * Resets the notification processing time tracker to zero. + */ + public function resetNotificationProcessingTime() : void{ $this->notificationProcessingTimeNs = 0; } + public function processNotifications() : void{ + $startTime = hrtime(true); $this->timings->startTiming(); try{ parent::processNotifications(); }finally{ + $this->notificationProcessingTimeNs += hrtime(true) - $startTime; $this->timings->stopTiming(); } } diff --git a/src/block/Block.php b/src/block/Block.php index 2e6dcb4ef..625509be4 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -253,6 +253,14 @@ class Block{ * Generates a block transaction to set all blocks affected by placing this block. Usually this is just the block * itself, but may be multiple blocks in some cases (such as doors). * + * @param BlockTransaction $tx Blocks to be set should be added to this transaction (do not modify thr world directly) + * @param Item $item Item used to place the block + * @param Block $blockReplace Block expected to be replaced + * @param Block $blockClicked Block that was clicked using the item + * @param int $face Face of the clicked block which was clicked + * @param Vector3 $clickVector Exact position inside the clicked block where the click occurred, relative to the block's position + * @param Player|null $player Player who placed the block, or null if it was not a player + * * @return bool whether the placement should go ahead */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{