mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 18:29:46 +00:00
Added Terminal class, Improved normal generator speed
This commit is contained in:
parent
328cd585c0
commit
b0f8c14640
@ -67,6 +67,7 @@ namespace {
|
||||
namespace pocketmine {
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
|
||||
@ -119,13 +120,14 @@ namespace pocketmine {
|
||||
ini_set("memory_limit", -1);
|
||||
define("pocketmine\\START_TIME", microtime(true));
|
||||
|
||||
$opts = getopt("", ["enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
|
||||
define("pocketmine\\DATA", isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
|
||||
define("pocketmine\\ANSI", (Utils::getOS() !== "win" or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"]));
|
||||
Terminal::init();
|
||||
|
||||
define("pocketmine\\ANSI", Terminal::hasFormattingCodes());
|
||||
|
||||
if(!file_exists(\pocketmine\DATA)){
|
||||
mkdir(\pocketmine\DATA, 0777, true);
|
||||
@ -468,6 +470,8 @@ namespace pocketmine {
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
echo Terminal::$FORMAT_RESET . "\n";
|
||||
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ use pocketmine\utils\Config;
|
||||
use pocketmine\utils\LevelException;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\ServerException;
|
||||
use pocketmine\utils\Terminal;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\TextWrapper;
|
||||
use pocketmine\utils\Utils;
|
||||
@ -1174,21 +1175,14 @@ class Server{
|
||||
|
||||
$this->getLogger()->notice("Spawn terrain for level \"$name\" is being generated in the background");
|
||||
|
||||
|
||||
$radiusSquared = ($this->getViewDistance() + 1) / M_PI;
|
||||
$radius = ceil(sqrt($radiusSquared));
|
||||
|
||||
$centerX = $level->getSpawnLocation()->getX() >> 4;
|
||||
$centerZ = $level->getSpawnLocation()->getZ() >> 4;
|
||||
|
||||
$order = [];
|
||||
|
||||
for($X = -$radius; $X <= $radius; ++$X){
|
||||
for($Z = -$radius; $Z <= $radius; ++$Z){
|
||||
for($X = -4; $X <= 4; ++$X){
|
||||
for($Z = -4; $Z <= 4; ++$Z){
|
||||
$distance = $X ** 2 + $Z ** 2;
|
||||
if($distance > $radiusSquared){
|
||||
continue;
|
||||
}
|
||||
$chunkX = $X + $centerX;
|
||||
$chunkZ = $Z + $centerZ;
|
||||
$index = Level::chunkHash($chunkX, $chunkZ);
|
||||
@ -2192,9 +2186,19 @@ class Server{
|
||||
}
|
||||
|
||||
private function titleTick(){
|
||||
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and \pocketmine\ANSI === true){
|
||||
echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . " | Online " . count($this->players) . "/" . $this->getMaxPlayers() . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "/" . round((memory_get_usage(true) / 1024) / 1024, 2) . " MB | U " . round($this->mainInterface->getUploadUsage() / 1024, 2) . " D " . round($this->mainInterface->getDownloadUsage() / 1024, 2) . " kB/s | TPS " . $this->getTicksPerSecond() . " | Load " . $this->getTickUsage() . "%\x07";
|
||||
if(!Terminal::hasFormattingCodes()){
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\x1b]0;" . $this->getName() . " " .
|
||||
$this->getPocketMineVersion() .
|
||||
" | Online " . count($this->players) . "/" . $this->getMaxPlayers() .
|
||||
" | RAM " . round((memory_get_usage() / 1024) / 1024, 2) .
|
||||
"/" . round((memory_get_usage(true) / 1024) / 1024, 2) .
|
||||
" MB | U " . round($this->mainInterface->getUploadUsage() / 1024, 2) .
|
||||
" D " . round($this->mainInterface->getDownloadUsage() / 1024, 2) .
|
||||
" kB/s | TPS " . $this->getTicksPerSecond() .
|
||||
" | Load " . $this->getTickUsage() . "%\x07";
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\level\generator;
|
||||
|
||||
use pocketmine\level\format\FullChunk;
|
||||
use pocketmine\level\generator\biome\Biome;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\utils\Binary;
|
||||
|
||||
@ -110,6 +111,7 @@ class GenerationManager{
|
||||
$this->logger = $logger;
|
||||
$this->loader = $loader;
|
||||
$chunkX = $chunkZ = null;
|
||||
Biome::init();
|
||||
|
||||
while($this->shutdown !== true){
|
||||
try{
|
||||
|
@ -194,15 +194,30 @@ abstract class Generator{
|
||||
for($yy = 0; $yy < $ySize; ++$yy){
|
||||
if($xx % $xSamplingRate !== 0 or $zz % $zSamplingRate !== 0 or $yy % $ySamplingRate !== 0){
|
||||
$nx = (int) ($xx / $xSamplingRate) * $xSamplingRate;
|
||||
$nz = (int) ($zz / $zSamplingRate) * $zSamplingRate;
|
||||
$ny = (int) ($yy / $ySamplingRate) * $ySamplingRate;
|
||||
$noiseArray[$xx][$zz][$yy] = Noise::trilinearLerp(
|
||||
$xx, $yy, $zz, $noiseArray[$nx][$nz][$ny], $noiseArray[$nx][$nz][$nny = $ny + $ySamplingRate],
|
||||
$noiseArray[$nx][$nnz = $nz + $zSamplingRate][$ny], $noiseArray[$nx][$nnz][$nny],
|
||||
$noiseArray[$nnx = $nx + $xSamplingRate][$nz][$ny], $noiseArray[$nnx][$nz][$nny],
|
||||
$noiseArray[$nnx][$nnz][$ny],
|
||||
$noiseArray[$nnx][$nnz][$nny],
|
||||
$nx, $nnx, $ny, $nny, $nz, $nnz
|
||||
$nz = (int) ($zz / $zSamplingRate) * $zSamplingRate;
|
||||
|
||||
$nnx = $nx + $xSamplingRate;
|
||||
$nny = $ny + $ySamplingRate;
|
||||
$nnz = $nz + $zSamplingRate;
|
||||
|
||||
$dx1 = (($nnx - $xx) / ($nnx - $nx));
|
||||
$dx2 = (($xx - $nx) / ($nnx - $nx));
|
||||
$dy1 = (($nny - $yy) / ($nny - $ny));
|
||||
$dy2 = (($yy - $ny) / ($nny - $ny));
|
||||
|
||||
$noiseArray[$xx][$zz][$yy] = (($nnz - $zz) / ($nnz - $nz)) * (
|
||||
$dy1 * (
|
||||
$dx1 * $noiseArray[$nx][$nz][$ny] + $dx2 * $noiseArray[$nnx][$nz][$ny]
|
||||
) + $dy2 * (
|
||||
$dx1 * $noiseArray[$nx][$nz][$nny] + $dx2 * $noiseArray[$nnx][$nz][$nny]
|
||||
)
|
||||
) + (($zz - $nz) / ($nnz - $nz)) * (
|
||||
$dy1 * (
|
||||
$dx1 * $noiseArray[$nx][$nnz][$ny] + $dx2 * $noiseArray[$nnx][$nnz][$ny]
|
||||
) + $dy2 * (
|
||||
$dx1 * $noiseArray[$nx][$nnz][$nny] + $dx2 * $noiseArray[$nnx][$nnz][$nny]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ abstract class Biome{
|
||||
|
||||
/** @var Biome[] */
|
||||
private static $biomes = [];
|
||||
private static $setup = false;
|
||||
|
||||
private $id;
|
||||
private $registered = false;
|
||||
@ -65,20 +64,17 @@ abstract class Biome{
|
||||
}
|
||||
|
||||
public static function init(){
|
||||
if(self::$setup === false){
|
||||
self::$setup = true;
|
||||
self::register(self::OCEAN, new OceanBiome());
|
||||
self::register(self::PLAINS, new PlainBiome());
|
||||
self::register(self::DESERT, new DesertBiome());
|
||||
self::register(self::MOUNTAINS, new MountainsBiome());
|
||||
self::register(self::FOREST, new ForestBiome());
|
||||
self::register(self::OCEAN, new OceanBiome());
|
||||
self::register(self::PLAINS, new PlainBiome());
|
||||
self::register(self::DESERT, new DesertBiome());
|
||||
self::register(self::MOUNTAINS, new MountainsBiome());
|
||||
self::register(self::FOREST, new ForestBiome());
|
||||
|
||||
self::register(self::RIVER, new RiverBiome());
|
||||
self::register(self::RIVER, new RiverBiome());
|
||||
|
||||
self::register(self::BEACH, new BeachBiome());
|
||||
self::register(self::BEACH, new BeachBiome());
|
||||
|
||||
self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome());
|
||||
}
|
||||
self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,9 @@ class BiomeSelector{
|
||||
* @return Biome
|
||||
*/
|
||||
public function pickBiome($x, $z){
|
||||
|
||||
return Biome::getBiome(Biome::PLAINS);
|
||||
|
||||
//$temperature = $this->temperature->noise2D($x, $z);
|
||||
$rainfall = $this->rainfall->noise2D($x, $z);
|
||||
|
||||
|
@ -127,10 +127,6 @@ class Normal extends Generator{
|
||||
|
||||
public function generateChunk($chunkX, $chunkZ){
|
||||
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
|
||||
//$hills = [];
|
||||
//$base = [];
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 8, 8, 8, $chunkX * 16, 0, $chunkZ * 16);
|
||||
|
||||
@ -175,15 +171,17 @@ class Normal extends Generator{
|
||||
}else{
|
||||
if($y <= $this->waterHeight){
|
||||
$chunk->setBlockId($x, $y, $z, Block::STILL_WATER);
|
||||
$lightValue = 15 - ($this->waterHeight - $y) * 2;
|
||||
if($lightValue > 0){
|
||||
$chunk->setBlockSkyLight($x, $y, $z, $lightValue);
|
||||
}
|
||||
}else{
|
||||
$chunk->setBlockSkyLight($x, $y, $z, 15);
|
||||
}
|
||||
$chunk->setBlockSkyLight($x, $y, $z, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var_dump((microtime(true) - $start) * 1000);
|
||||
}
|
||||
|
||||
public function populateChunk($chunkX, $chunkZ){
|
||||
|
@ -35,13 +35,13 @@ chunk-sending:
|
||||
#Amount of chunks sent to players per tick
|
||||
per-tick: 4
|
||||
#Compression level used when sending chunks. Higher = more CPU, less bandwidth usage
|
||||
compression-level: 8
|
||||
compression-level: 7
|
||||
#Amount of chunks sent around each player
|
||||
max-chunks: 256
|
||||
|
||||
chunk-ticking:
|
||||
#Max amount of chunks processed each tick
|
||||
per-tick: 260
|
||||
per-tick: 80
|
||||
#Radius of chunks around a player to tick
|
||||
tick-radius: 4
|
||||
#NOTE: This is currently not implemented
|
||||
|
@ -27,7 +27,6 @@ class MainLogger extends \AttachableThreadedLogger{
|
||||
protected $logFile;
|
||||
protected $logStream;
|
||||
protected $shutdown;
|
||||
protected $hasANSI;
|
||||
protected $logDebug;
|
||||
private $logResource;
|
||||
/** @var MainLogger */
|
||||
@ -35,19 +34,17 @@ class MainLogger extends \AttachableThreadedLogger{
|
||||
|
||||
/**
|
||||
* @param string $logFile
|
||||
* @param bool $hasANSI
|
||||
* @param bool $logDebug
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($logFile, $hasANSI = false, $logDebug = false){
|
||||
public function __construct($logFile, $logDebug = false){
|
||||
if(static::$logger instanceof MainLogger){
|
||||
throw new \RuntimeException("MainLogger has been already created");
|
||||
}
|
||||
static::$logger = $this;
|
||||
touch($logFile);
|
||||
$this->logFile = $logFile;
|
||||
$this->hasANSI = (bool) $hasANSI;
|
||||
$this->logDebug = (bool) $logDebug;
|
||||
$this->logStream = "";
|
||||
$this->start(PTHREADS_INHERIT_NONE);
|
||||
@ -181,12 +178,12 @@ class MainLogger extends \AttachableThreadedLogger{
|
||||
protected function send($message, $level = -1){
|
||||
$now = time();
|
||||
$message = TextFormat::toANSI(TextFormat::AQUA . date("H:i:s", $now) . TextFormat::RESET . " " . $message . TextFormat::RESET . PHP_EOL);
|
||||
$cleanMessage = TextFormat::clean(preg_replace('/\x1b\[[0-9;]*m/', "", $message));
|
||||
$cleanMessage = TextFormat::clean($message);
|
||||
|
||||
if(!$this->hasANSI){
|
||||
if(!Terminal::hasFormattingCodes()){
|
||||
echo $cleanMessage;
|
||||
}else{
|
||||
echo $message;
|
||||
echo Terminal::$START_LINE . $message . Terminal::$END_LINE;
|
||||
}
|
||||
|
||||
if($this->attachment instanceof \ThreadedLoggerAttachment){
|
||||
|
122
src/pocketmine/utils/Terminal.php
Normal file
122
src/pocketmine/utils/Terminal.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
abstract class Terminal{
|
||||
|
||||
public static $START_LINE = "";
|
||||
public static $END_LINE = "";
|
||||
|
||||
public static $FORMAT_BOLD = "";
|
||||
public static $FORMAT_OBFUSCATED = "";
|
||||
public static $FORMAT_ITALIC = "";
|
||||
public static $FORMAT_UNDERLINE = "";
|
||||
public static $FORMAT_STRIKETHROUGH = "";
|
||||
|
||||
public static $FORMAT_RESET = "";
|
||||
|
||||
public static $COLOR_BLACK = "";
|
||||
public static $COLOR_DARK_BLUE = "";
|
||||
public static $COLOR_DARK_GREEN = "";
|
||||
public static $COLOR_DARK_AQUA = "";
|
||||
public static $COLOR_DARK_RED = "";
|
||||
public static $COLOR_PURPLE = "";
|
||||
public static $COLOR_GOLD = "";
|
||||
public static $COLOR_GRAY = "";
|
||||
public static $COLOR_DARK_GRAY = "";
|
||||
public static $COLOR_BLUE = "";
|
||||
public static $COLOR_GREEN = "";
|
||||
public static $COLOR_AQUA = "";
|
||||
public static $COLOR_RED = "";
|
||||
public static $COLOR_LIGHT_PURPLE = "";
|
||||
public static $COLOR_YELLOW = "";
|
||||
public static $COLOR_WHITE = "";
|
||||
|
||||
private static $formattingCodes = null;
|
||||
|
||||
public static function hasFormattingCodes(){
|
||||
if(self::$formattingCodes === null){
|
||||
$opts = getopt("", ["enable-ansi", "disable-ansi"]);
|
||||
if(isset($opts["disable-ansi"])){
|
||||
self::$hasFormattingCodes = false;
|
||||
}
|
||||
self::$formattingCodes = ((Utils::getOS() !== "win" and getenv("TERM") !== "") or isset($opts["enable-ansi"]));
|
||||
}
|
||||
|
||||
return self::$formattingCodes;
|
||||
}
|
||||
|
||||
protected static function getEscapeCodes(){
|
||||
self::$FORMAT_BOLD = `tput bold`;
|
||||
self::$FORMAT_OBFUSCATED = `tput invis`;
|
||||
self::$FORMAT_ITALIC = `tput sitm`;
|
||||
self::$FORMAT_UNDERLINE = `tput smul`;
|
||||
self::$FORMAT_STRIKETHROUGH = "\x1b[9m"; //`tput `;
|
||||
|
||||
self::$FORMAT_RESET = `tput sgr0`;
|
||||
|
||||
$colors = (int) `tput colors`;
|
||||
if($colors > 8){
|
||||
self::$COLOR_BLACK = $colors >= 256 ? `tput setaf 16` : `tput setaf 0`;
|
||||
self::$COLOR_DARK_BLUE = $colors >= 256 ? `tput setaf 19` : `tput setaf 4`;
|
||||
self::$COLOR_DARK_GREEN = $colors >= 256 ? `tput setaf 34` : `tput setaf 2`;
|
||||
self::$COLOR_DARK_AQUA = $colors >= 256 ? `tput setaf 37` : `tput setaf 6`;
|
||||
self::$COLOR_DARK_RED = $colors >= 256 ? `tput setaf 124` : `tput setaf 1`;
|
||||
self::$COLOR_PURPLE = $colors >= 256 ? `tput setaf 127` : `tput setaf 5`;
|
||||
self::$COLOR_GOLD = $colors >= 256 ? `tput setaf 214` : `tput setaf 3`;
|
||||
self::$COLOR_GRAY = $colors >= 256 ? `tput setaf 145` : `tput setaf 7`;
|
||||
self::$COLOR_DARK_GRAY = $colors >= 256 ? `tput setaf 59` : `tput setaf 8`;
|
||||
self::$COLOR_BLUE = $colors >= 256 ? `tput setaf 63` : `tput setaf 12`;
|
||||
self::$COLOR_GREEN = $colors >= 256 ? `tput setaf 83` : `tput setaf 10`;
|
||||
self::$COLOR_AQUA = $colors >= 256 ? `tput setaf 87` : `tput setaf 14`;
|
||||
self::$COLOR_RED = $colors >= 256 ? `tput setaf 203` : `tput setaf 9`;
|
||||
self::$COLOR_LIGHT_PURPLE = $colors >= 256 ? `tput setaf 207` : `tput setaf 13`;
|
||||
self::$COLOR_YELLOW = $colors >= 256 ? `tput setaf 227` : `tput setaf 11`;
|
||||
self::$COLOR_WHITE = $colors >= 256 ? `tput setaf 231` : `tput setaf 15`;
|
||||
}else{
|
||||
self::$COLOR_BLACK = self::$COLOR_DARK_GRAY = `tput setaf 0`;
|
||||
self::$COLOR_RED = self::$COLOR_DARK_RED = `tput setaf 1`;
|
||||
self::$COLOR_GREEN = self::$COLOR_DARK_GREEN = `tput setaf 2`;
|
||||
self::$COLOR_YELLOW = self::$COLOR_GOLD = `tput setaf 3`;
|
||||
self::$COLOR_BLUE = self::$COLOR_DARK_BLUE = `tput setaf 4`;
|
||||
self::$COLOR_LIGHT_PURPLE = self::$COLOR_PURPLE = `tput setaf 5`;
|
||||
self::$COLOR_AQUA = self::$COLOR_DARK_AQUA = `tput setaf 6`;
|
||||
self::$COLOR_GRAY = self::$COLOR_WHITE = `tput setaf 7`;
|
||||
}
|
||||
|
||||
self::$START_LINE = `tput sc` . "\n" . `tput cuu1` . "\r";
|
||||
self::$END_LINE = `tput rc`;
|
||||
}
|
||||
|
||||
public static function init(){
|
||||
switch(Utils::getOS()){
|
||||
case "linux":
|
||||
case "mac":
|
||||
case "bsd":
|
||||
self::getEscapeCodes();
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: Android, Windows iOS
|
||||
}
|
||||
|
||||
}
|
@ -68,7 +68,7 @@ abstract class TextFormat{
|
||||
* @return mixed
|
||||
*/
|
||||
public static function clean($string){
|
||||
return preg_replace(["/§[0123456789abcdefklmnor]/", "/\\x1b*/"], "", $string);
|
||||
return preg_replace(["/§[0123456789abcdefklmnor]/", "/\x1b\\[[0-9;]+m/"], "", $string);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -386,26 +386,27 @@ abstract class TextFormat{
|
||||
if(!is_array($string)){
|
||||
$string = self::tokenize($string);
|
||||
}
|
||||
|
||||
$newString = "";
|
||||
foreach($string as $token){
|
||||
switch($token){
|
||||
case TextFormat::BOLD:
|
||||
$newString .= "\x1b[1m";
|
||||
$newString .= Terminal::$FORMAT_BOLD;
|
||||
break;
|
||||
case TextFormat::OBFUSCATED:
|
||||
$newString .= "\x1b[8m";
|
||||
$newString .= Terminal::$FORMAT_OBFUSCATED;
|
||||
break;
|
||||
case TextFormat::ITALIC:
|
||||
$newString .= "\x1b[3m";
|
||||
$newString .= Terminal::$FORMAT_ITALIC;
|
||||
break;
|
||||
case TextFormat::UNDERLINE:
|
||||
$newString .= "\x1b[4m";
|
||||
$newString .= Terminal::$FORMAT_UNDERLINE;
|
||||
break;
|
||||
case TextFormat::STRIKETHROUGH:
|
||||
$newString .= "\x1b[9m";
|
||||
$newString .= Terminal::$FORMAT_STRIKETHROUGH;
|
||||
break;
|
||||
case TextFormat::RESET:
|
||||
$newString .= "\x1b[0m";
|
||||
$newString .= Terminal::$FORMAT_RESET;
|
||||
break;
|
||||
|
||||
//Colors
|
||||
|
Loading…
x
Reference in New Issue
Block a user