diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index cea6bf876..8f3afc8d1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -180,6 +180,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ protected $stepHeight = 0.6; public $usedChunks = []; + protected $chunkLoadCount = 0; protected $loadQueue = []; protected $nextChunkOrderRun = 5; @@ -565,6 +566,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } $this->usedChunks[Level::chunkHash($x, $z)] = true; + $this->chunkLoadCount++; $pk = new FullChunkDataPacket(); $pk->chunkX = $x; @@ -608,7 +610,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->level->requestChunk($X, $Z, $this, LevelProvider::ORDER_ZXY); } - if(count($this->usedChunks) >= $this->spawnThreshold and $this->spawned === false){ + if($this->chunkLoadCount >= $this->spawnThreshold and $this->spawned === false){ $this->spawned = true; $this->sendSettings(); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2fe040816..4d299333a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -220,6 +220,8 @@ class Server{ /** @var Level[] */ private $levels = []; + private $offendingLevels = []; + private $offendingTicks = []; /** @var Level */ private $levelDefault = null; @@ -1971,14 +1973,12 @@ class Server{ * Starts the PocketMine-MP server and starts processing ticks and packets */ public function start(){ - if($this->getConfigBoolean("enable-query", true) === true){ $this->queryHandler = new QueryHandler(); - } foreach($this->getIPBans()->getEntries() as $entry){ - $this->blockAddress($entry->getName(), -1); + $this->network->blockAddress($entry->getName(), -1); } if($this->getProperty("settings.send-usage", true) !== false){ @@ -2144,10 +2144,28 @@ class Server{ private function checkTickUpdates($currentTick){ + $tickLimit = 50 / count($this->levels); + $levelTimes = []; + + $startTime = microtime(true); //Do level ticks foreach($this->getLevels() as $level){ + if(isset($this->offendingLevels[$level->getId()]) and $this->offendingTicks[$level->getId()]-- > 0){ + continue; + } try{ + $levelTime = microtime(true); $level->doTick($currentTick); + $levelMs = (microtime(true) - $levelTime) * 1000; + $levelTimes[$level->getId()] = $levelMs; + if(isset($this->offendingLevels[$level->getId()])){ + if($levelMs < $tickLimit and --$this->offendingLevels[$level->getId()] <= 0){ + unset($this->offendingLevels[$level->getId()]); + unset($this->offendingTicks[$level->getId()]); + }else{ + $this->offendingTicks[$level->getId()] = $this->offendingLevels[$level->getId()]; + } + } }catch(\Exception $e){ $this->logger->critical("Could not tick level " . $level->getName() . ": " . $e->getMessage()); if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){ @@ -2155,6 +2173,26 @@ class Server{ } } } + + $totalTime = (microtime(true) - $startTime) * 1000; + + if($totalTime > 50){ + arsort($levelTimes); + foreach($levelTimes as $levelId => $t){ + $totalTime -= $t; + if(!isset($this->offendingLevels[$levelId])){ + $this->offendingLevels[$levelId] = max(1, min(10, floor($t / 50))); + }elseif($this->offendingLevels[$levelId] < 10){ //Limit? + ++$this->offendingLevels[$levelId]; + } + $this->offendingTicks[$levelId] = $this->offendingLevels[$levelId]; + + if($totalTime <= 50){ + break; + } + } + } + } public function doAutoSave(){ diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/pocketmine/command/defaults/BanIpCommand.php index 7cf9fc0d0..82432ca07 100644 --- a/src/pocketmine/command/defaults/BanIpCommand.php +++ b/src/pocketmine/command/defaults/BanIpCommand.php @@ -75,7 +75,7 @@ class BanIpCommand extends VanillaCommand{ } } - $sender->getServer()->blockAddress($ip, -1); + $sender->getServer()->getNetwork()->blockAddress($ip, -1); Command::broadcastCommandMessage($sender, "Banned IP Address " . $ip); } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index c24c61593..b61f7f6d0 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -79,10 +79,17 @@ class Normal extends Generator{ private static function generateKernel(){ self::$GAUSSIAN_KERNEL = []; + + $bellSize = 1 / self::$SMOOTH_SIZE; + $bellHeight = 2 * self::$SMOOTH_SIZE; + for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = []; + for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = 10 / sqrt($sx ** 2 + $sz ** 2 + 0.2); + $bx = $bellSize * $sx; + $bz = $bellSize * $sz; + self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); } } } @@ -195,6 +202,8 @@ class Normal extends Generator{ $chunk = $this->level->getChunk($chunkX, $chunkZ); + $biomeCache = []; + for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ $minSum = 0; @@ -208,12 +217,20 @@ class Normal extends Generator{ for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ - $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); - $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] / (($biome->getMaxElevation() - $this->waterHeight) / $this->waterHeight + 2); - if($adjacent->getMaxElevation() > $biome->getMaxElevation()){ - $weight /= 2; + $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE]; + + if($sx === 0 and $sz === 0){ + $adjacent = $biome; + }else{ + $index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); + if(isset($biomeCache[$index])){ + $adjacent = $biomeCache[$index]; + }else{ + $biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); + } } + $minSum += $adjacent->getMinElevation() * $weight; $maxSum += $adjacent->getMaxElevation() * $weight; $weightSum += $weight; diff --git a/src/pocketmine/utils/Random.php b/src/pocketmine/utils/Random.php index c62e8b3e4..288472986 100644 --- a/src/pocketmine/utils/Random.php +++ b/src/pocketmine/utils/Random.php @@ -62,14 +62,13 @@ class Random{ * @return int */ public function nextSignedInt(){ - $t = crc32(pack("N", $this->seed)); + $t = ((($this->seed * 65535) + 31337) >> 8) + 1337; + if(PHP_INT_SIZE === 8){ + $t = $t << 32 >> 32; + } $this->seed ^= $t; - if(PHP_INT_SIZE === 8){ - return $t << 32 >> 32; - }else{ - return $t; - } + return $t; } /**