/** * Tries to execute a server tick */ private function tick() { $tickTime = microtime(true); if ($tickTime - $this->nextTick < -0.025) { //Allow half a tick of diff return false; } Timings::$serverTickTimer->startTiming(); ++$this->tickCounter; $this->checkConsole(); Timings::$connectionTimer->startTiming(); $this->network->processInterfaces(); if ($this->rcon !== null) { $this->rcon->check(); } Timings::$connectionTimer->stopTiming(); Timings::$schedulerTimer->startTiming(); $this->scheduler->mainThreadHeartbeat($this->tickCounter); Timings::$schedulerTimer->stopTiming(); $this->checkTickUpdates($this->tickCounter, $tickTime); foreach ($this->players as $player) { $player->checkNetwork(); } if (($this->tickCounter & 0b1111) === 0) { $this->titleTick(); $this->maxTick = 20; $this->maxUse = 0; if (($this->tickCounter & 0b111111111) === 0) { try { $this->getPluginManager()->callEvent($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5)); if ($this->queryHandler !== null) { $this->queryHandler->regenerateInfo(); } } catch (\Exception $e) { if ($this->logger instanceof MainLogger) { $this->logger->logException($e); } } } $this->getNetwork()->updateName(); } if ($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks) { $this->autoSaveTicker = 0; $this->doAutoSave(); } if ($this->sendUsageTicker > 0 and --$this->sendUsageTicker === 0) { $this->sendUsageTicker = 6000; $this->sendUsage(SendUsageTask::TYPE_STATUS); } if ($this->tickCounter % 100 === 0) { foreach ($this->levels as $level) { $level->clearCache(); } if ($this->getTicksPerSecondAverage() < 12) { $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.tickOverload")); } } if ($this->dispatchSignals and $this->tickCounter % 5 === 0) { pcntl_signal_dispatch(); } $this->getMemoryManager()->check(); Timings::$serverTickTimer->stopTiming(); $now = microtime(true); $tick = min(20, 1 / max(0.001, $now - $tickTime)); $use = min(1, ($now - $tickTime) / 0.05); TimingsHandler::tick($tick <= $this->profilingTickRate); if ($this->maxTick > $tick) { $this->maxTick = $tick; } if ($this->maxUse < $use) { $this->maxUse = $use; } array_shift($this->tickAverage); $this->tickAverage[] = $tick; array_shift($this->useAverage); $this->useAverage[] = $use; if ($this->nextTick - $tickTime < -1) { $this->nextTick = $tickTime; } else { $this->nextTick += 0.05; } return true; }
public function forceShutdown() { if ($this->hasStopped) { return; } try { $this->hasStopped = true; $this->shutdown(); if ($this->rcon instanceof RCON) { $this->rcon->stop(); } if ($this->getProperty("settings.upnp-forwarding", false) === true) { $this->logger->info("[UPnP] Removing port forward..."); UPnP::RemovePortForward($this->getPort()); } $this->pluginManager->disablePlugins(); foreach ($this->players as $player) { $player->close(TextFormat::YELLOW . $player->getName() . " has left the game", $this->getProperty("settings.shutdown-message", "Server closed")); } foreach ($this->getLevels() as $level) { $this->unloadLevel($level, true); } if ($this->generationManager instanceof GenerationRequestManager) { $this->generationManager->shutdown(); } HandlerList::unregisterAll(); $this->scheduler->cancelAllTasks(); $this->scheduler->mainThreadHeartbeat(PHP_INT_MAX); $this->properties->save(); $this->console->kill(); foreach ($this->network->getInterfaces() as $interface) { $interface->shutdown(); $this->network->unregisterInterface($interface); } } catch (\Exception $e) { $this->logger->emergency("Crashed while crashing, killing process"); @kill(getmypid()); } }