From 5d531b56dbf156320296a836723967575f2ea671 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 16:58:56 +0100 Subject: [PATCH 01/13] travis.sh: lock down PHPUnit at 7.5.11 7.5.12 makes changes which assume libxml is present, which isn't the case with our PHP builds. --- tests/travis.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/travis.sh b/tests/travis.sh index cfaaa462b..b0ccce1e8 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -22,7 +22,8 @@ if [ $? -ne 0 ]; then fi #Run PHPUnit tests -curl https://phar.phpunit.de/phpunit-7.phar --silent --location -o phpunit.phar +#7.5.12 introduces changes that set the build on fire because we don't ship libxml - TODO FIX +curl https://phar.phpunit.de/phpunit-7.5.11.phar --silent --location -o phpunit.phar "$PHP_BINARY" phpunit.phar --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit || exit 1 #Run-the-server tests From 2a5561fcd1c56ffaea1a2075d25a43c6068b436f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 19:51:59 +0100 Subject: [PATCH 02/13] added more MultiRecipe UUIDs --- src/pocketmine/inventory/MultiRecipe.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/inventory/MultiRecipe.php b/src/pocketmine/inventory/MultiRecipe.php index 0e55cb6d1..d9e667464 100644 --- a/src/pocketmine/inventory/MultiRecipe.php +++ b/src/pocketmine/inventory/MultiRecipe.php @@ -28,12 +28,16 @@ use pocketmine\utils\UUID; class MultiRecipe{ public const TYPE_REPAIR_ITEM = "00000000-0000-0000-0000-000000000001"; public const TYPE_MAP_EXTENDING = "D392B075-4BA1-40AE-8789-AF868D56F6CE"; + public const TYPE_MAP_EXTENDING_CARTOGRAPHY = "8B36268C-1829-483C-A0F1-993B7156A8F2"; public const TYPE_MAP_CLONING = "85939755-BA10-4D9D-A4CC-EFB7A8E943C4"; + public const TYPE_MAP_CLONING_CARTOGRAPHY = "442D85ED-8272-4543-A6F1-418F90DED05D"; public const TYPE_MAP_UPGRADING = "AECD2294-4B94-434B-8667-4499BB2C9327"; + public const TYPE_MAP_UPGRADING_CARTOGRAPHY = "98C84B38-1085-46BD-B1CE-DD38C159E6CC"; public const TYPE_BOOK_CLONING = "D1CA6B84-338E-4F2F-9C6B-76CC8B4BD98D"; public const TYPE_BANNER_DUPLICATE = "B5C5D105-75A2-4076-AF2B-923EA2BF4BF0"; public const TYPE_BANNER_ADD_PATTERN = "D81AAEAF-E172-4440-9225-868DF030D27B"; public const TYPE_FIREWORKS = "00000000-0000-0000-0000-000000000002"; + public const TYPE_MAP_LOCKING_CARTOGRAPHY = "602234E4-CAC1-4353-8BB7-B1EBFF70024B"; private $uuid; From 6161155660a9adff36f804216e6ad8e9729f3ed8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 14:05:37 +0100 Subject: [PATCH 03/13] CraftingManager: micro optimization: reuse closure for item deserialize & reduce indirection --- src/pocketmine/inventory/CraftingManager.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 91805188e..528b364a9 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -53,6 +53,7 @@ class CraftingManager{ public function init() : void{ $recipes = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "recipes.json"), true); + $itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']); foreach($recipes as $recipe){ switch($recipe["type"]){ case "shapeless": @@ -60,8 +61,8 @@ class CraftingManager{ break; } $this->registerRecipe(new ShapelessRecipe( - array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]), - array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["output"]) + array_map($itemDeserializerFunc, $recipe["input"]), + array_map($itemDeserializerFunc, $recipe["output"]) )); break; case "shaped": @@ -70,8 +71,8 @@ class CraftingManager{ } $this->registerRecipe(new ShapedRecipe( $recipe["shape"], - array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]), - array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["output"]) + array_map($itemDeserializerFunc, $recipe["input"]), + array_map($itemDeserializerFunc, $recipe["output"]) )); break; case "smelting": From 4d54dc30c19759c77eb7bf6dfeb300c8f2d863fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 14:11:08 +0100 Subject: [PATCH 04/13] crafting: deprecate some stuff that's been removed on bleeding edge --- src/pocketmine/inventory/CraftingManager.php | 8 +++++--- src/pocketmine/inventory/FurnaceRecipe.php | 5 +++++ src/pocketmine/inventory/Recipe.php | 5 +++++ src/pocketmine/inventory/ShapedRecipe.php | 5 +++++ src/pocketmine/inventory/ShapelessRecipe.php | 5 +++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 528b364a9..33dba506f 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -60,7 +60,7 @@ class CraftingManager{ if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics break; } - $this->registerRecipe(new ShapelessRecipe( + $this->registerShapelessRecipe(new ShapelessRecipe( array_map($itemDeserializerFunc, $recipe["input"]), array_map($itemDeserializerFunc, $recipe["output"]) )); @@ -69,7 +69,7 @@ class CraftingManager{ if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics break; } - $this->registerRecipe(new ShapedRecipe( + $this->registerShapedRecipe(new ShapedRecipe( $recipe["shape"], array_map($itemDeserializerFunc, $recipe["input"]), array_map($itemDeserializerFunc, $recipe["output"]) @@ -79,7 +79,7 @@ class CraftingManager{ if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics break; } - $this->registerRecipe(new FurnaceRecipe( + $this->registerFurnaceRecipe(new FurnaceRecipe( Item::jsonDeserialize($recipe["output"]), Item::jsonDeserialize($recipe["input"])) ); @@ -300,6 +300,8 @@ class CraftingManager{ } /** + * @deprecated + * * @param Recipe $recipe */ public function registerRecipe(Recipe $recipe) : void{ diff --git a/src/pocketmine/inventory/FurnaceRecipe.php b/src/pocketmine/inventory/FurnaceRecipe.php index c8ed4be61..8e81fe03f 100644 --- a/src/pocketmine/inventory/FurnaceRecipe.php +++ b/src/pocketmine/inventory/FurnaceRecipe.php @@ -63,6 +63,11 @@ class FurnaceRecipe implements Recipe{ return clone $this->output; } + /** + * @deprecated + * + * @param CraftingManager $manager + */ public function registerToCraftingManager(CraftingManager $manager) : void{ $manager->registerFurnaceRecipe($this); } diff --git a/src/pocketmine/inventory/Recipe.php b/src/pocketmine/inventory/Recipe.php index 883eea6d9..bdd72e01f 100644 --- a/src/pocketmine/inventory/Recipe.php +++ b/src/pocketmine/inventory/Recipe.php @@ -25,5 +25,10 @@ namespace pocketmine\inventory; interface Recipe{ + /** + * @deprecated + * + * @param CraftingManager $manager + */ public function registerToCraftingManager(CraftingManager $manager) : void; } diff --git a/src/pocketmine/inventory/ShapedRecipe.php b/src/pocketmine/inventory/ShapedRecipe.php index 04103cbfb..434eb36d5 100644 --- a/src/pocketmine/inventory/ShapedRecipe.php +++ b/src/pocketmine/inventory/ShapedRecipe.php @@ -187,6 +187,11 @@ class ShapedRecipe implements CraftingRecipe{ return $this->shape; } + /** + * @deprecated + * + * @param CraftingManager $manager + */ public function registerToCraftingManager(CraftingManager $manager) : void{ $manager->registerShapedRecipe($this); } diff --git a/src/pocketmine/inventory/ShapelessRecipe.php b/src/pocketmine/inventory/ShapelessRecipe.php index fcf303d43..170faab54 100644 --- a/src/pocketmine/inventory/ShapelessRecipe.php +++ b/src/pocketmine/inventory/ShapelessRecipe.php @@ -111,6 +111,11 @@ class ShapelessRecipe implements CraftingRecipe{ return $count; } + /** + * @deprecated + * + * @param CraftingManager $manager + */ public function registerToCraftingManager(CraftingManager $manager) : void{ $manager->registerShapelessRecipe($this); } From 4e5a80c4817615aad59ac7371205f6556dbbff7a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 14:12:49 +0100 Subject: [PATCH 05/13] Recipe: deprecate interface --- src/pocketmine/inventory/Recipe.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/inventory/Recipe.php b/src/pocketmine/inventory/Recipe.php index bdd72e01f..f97e985b9 100644 --- a/src/pocketmine/inventory/Recipe.php +++ b/src/pocketmine/inventory/Recipe.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; +/** + * @deprecated + */ interface Recipe{ /** From eedea4998bf77d9d6436e7f000de37596fe8d91e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 11:28:25 +0000 Subject: [PATCH 06/13] Terminal: Added write() and writeLine() to allow easily emitting Minecraft-formatted text to the console --- src/pocketmine/utils/MainLogger.php | 2 +- src/pocketmine/utils/Terminal.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 83d0f379b..06d11da64 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -307,7 +307,7 @@ class MainLogger extends \AttachableThreadedLogger{ } $this->synchronized(function() use ($message, $level, $time) : void{ - echo Terminal::toANSI($message) . PHP_EOL; + Terminal::writeLine($message); foreach($this->attachments as $attachment){ $attachment->call($level, $message); diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index dd52d6951..a3f6058c9 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -263,4 +263,23 @@ abstract class Terminal{ return $newString; } + + /** + * Emits a string containing Minecraft colour codes to the console formatted with native colours. + * + * @param string $line + */ + public static function write(string $line) : void{ + echo self::toANSI($line); + } + + /** + * Emits a string containing Minecraft colour codes to the console formatted with native colours, followed by a + * newline character. + * + * @param string $line + */ + public static function writeLine(string $line) : void{ + echo self::toANSI($line) . PHP_EOL; + } } From eaa78fe84992ac869c64056fc410135a64b9f9c3 Mon Sep 17 00:00:00 2001 From: "Jack M. Taylor" <32965703+JackMD@users.noreply.github.com> Date: Thu, 14 Feb 2019 15:58:19 +0500 Subject: [PATCH 07/13] backport 205e13d88: Config: add getPath() (#2758) Config->getPath() returns the path of the config i.e. the place where the config file is located. --- src/pocketmine/utils/Config.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 13d47f4d8..9fbd06bb6 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -248,6 +248,15 @@ class Config{ } } + /** + * Returns the path of the config. + * + * @return string + */ + public function getPath() : string{ + return $this->file; + } + /** * Sets the options for the JSON encoding when saving * From 680cdb8e3e5f76eb0ad1f4d15264ea0eec0e4c76 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 17:39:13 +0000 Subject: [PATCH 08/13] backport f5dbbea5f: Utils: added recursiveUnlink() --- src/pocketmine/utils/Utils.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index ef2fb0d34..a2fdf85a0 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -54,6 +54,8 @@ use function gettype; use function hexdec; use function implode; use function is_array; +use function is_dir; +use function is_file; use function is_object; use function is_readable; use function is_string; @@ -72,6 +74,8 @@ use function preg_match_all; use function preg_replace; use function proc_close; use function proc_open; +use function rmdir; +use function scandir; use function sha1; use function spl_object_hash; use function str_pad; @@ -85,11 +89,13 @@ use function strtolower; use function substr; use function sys_get_temp_dir; use function trim; +use function unlink; use function xdebug_get_function_stack; use const PHP_EOL; use const PHP_INT_MAX; use const PHP_INT_SIZE; use const PHP_MAXPATHLEN; +use const SCANDIR_SORT_NONE; use const STR_PAD_LEFT; use const STR_PAD_RIGHT; @@ -734,4 +740,22 @@ class Utils{ throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($subject) . "` must be compatible with `" . $sigType . "`"); } } + + public static function recursiveUnlink(string $dir) : void{ + if(is_dir($dir)){ + $objects = scandir($dir, SCANDIR_SORT_NONE); + foreach($objects as $object){ + if($object !== "." and $object !== ".."){ + if(is_dir($dir . "/" . $object)){ + self::recursiveUnlink($dir . "/" . $object); + }else{ + unlink($dir . "/" . $object); + } + } + } + rmdir($dir); + }elseif(is_file($dir)){ + unlink($dir); + } + } } From d0d300a6f84e2d72c32bccd9027195cd1218e01f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Apr 2019 18:32:15 +0100 Subject: [PATCH 09/13] backport 342b48b75: VersionString: Use the correct bitwise operators --- src/pocketmine/utils/VersionString.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/VersionString.php b/src/pocketmine/utils/VersionString.php index dd01356d0..e9a5f3c60 100644 --- a/src/pocketmine/utils/VersionString.php +++ b/src/pocketmine/utils/VersionString.php @@ -70,7 +70,7 @@ class VersionString{ } public function getNumber() : int{ - return (($this->major << 9) + ($this->minor << 5) + $this->patch); + return (($this->major << 9) | ($this->minor << 5) | $this->patch); } public function getBaseVersion() : string{ From a8433697adb44026bf236646f56d193108455824 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 11:54:44 +0000 Subject: [PATCH 10/13] backport aaaddd1fd: Terminal: stick a RESET on the end when writing a newline --- src/pocketmine/utils/Terminal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index a3f6058c9..67e89226b 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -280,6 +280,6 @@ abstract class Terminal{ * @param string $line */ public static function writeLine(string $line) : void{ - echo self::toANSI($line) . PHP_EOL; + echo self::toANSI($line) . self::$FORMAT_RESET . PHP_EOL; } } From 4635b93f4dc261e529db26e4442e82daab8b334f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:57:32 +0000 Subject: [PATCH 11/13] backport 23071d257 + deprecations: Extract process-related functions from Utils into a separate Process class --- src/pocketmine/MemoryManager.php | 3 +- src/pocketmine/PocketMine.php | 7 +- src/pocketmine/Server.php | 11 +- .../command/defaults/StatusCommand.php | 8 +- .../event/server/LowMemoryEvent.php | 4 +- src/pocketmine/scheduler/SendUsageTask.php | 5 +- src/pocketmine/utils/Process.php | 170 ++++++++++++++++++ src/pocketmine/utils/ServerKiller.php | 2 +- src/pocketmine/utils/Utils.php | 125 +++---------- 9 files changed, 218 insertions(+), 117 deletions(-) create mode 100644 src/pocketmine/utils/Process.php diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index d6e03a393..77ecca9d4 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -27,6 +27,7 @@ use pocketmine\event\server\LowMemoryEvent; use pocketmine\scheduler\DumpWorkerMemoryTask; use pocketmine\scheduler\GarbageCollectionTask; use pocketmine\timings\Timings; +use pocketmine\utils\Process; use pocketmine\utils\Utils; use function arsort; use function count; @@ -236,7 +237,7 @@ class MemoryManager{ if(($this->memoryLimit > 0 or $this->globalMemoryLimit > 0) and ++$this->checkTicker >= $this->checkRate){ $this->checkTicker = 0; - $memory = Utils::getMemoryUsage(true); + $memory = Process::getMemoryUsage(true); $trigger = false; if($this->memoryLimit > 0 and $memory[0] > $this->memoryLimit){ $trigger = 0; diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 732026434..4b79ed5da 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -29,6 +29,7 @@ namespace { namespace pocketmine { use pocketmine\utils\MainLogger; + use pocketmine\utils\Process; use pocketmine\utils\ServerKiller; use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; @@ -238,9 +239,9 @@ namespace pocketmine { $gitHash = str_repeat("00", 20); if(\Phar::running(true) === ""){ - if(Utils::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ + if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ $gitHash = trim($out); - if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified + if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified $gitHash .= "-dirty"; } } @@ -283,7 +284,7 @@ namespace pocketmine { if(\pocketmine\DEBUG > 1){ echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL; } - Utils::kill(getmypid()); + Process::kill(getmypid()); } }while(false); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 8de8151d4..3468c6c83 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -101,6 +101,7 @@ use pocketmine\updater\AutoUpdater; use pocketmine\utils\Config; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; +use pocketmine\utils\Process; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -2150,7 +2151,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); $this->logger->emergency("Crashed while crashing, killing process"); - @Utils::kill(getmypid()); + @Process::kill(getmypid()); } } @@ -2326,7 +2327,7 @@ class Server{ echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); } - @Utils::kill(getmypid()); + @Process::kill(getmypid()); exit(1); } @@ -2507,10 +2508,10 @@ class Server{ private function titleTick(){ Timings::$titleTickTimer->startTiming(); - $d = Utils::getRealMemoryUsage(); + $d = Process::getRealMemoryUsage(); - $u = Utils::getMemoryUsage(true); - $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Utils::getThreadCount()); + $u = Process::getMemoryUsage(true); + $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Process::getThreadCount()); echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index d43f7df28..9fb0253bb 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\utils\Process; use pocketmine\utils\TextFormat; -use pocketmine\utils\Utils; use function count; use function floor; use function microtime; @@ -48,8 +48,8 @@ class StatusCommand extends VanillaCommand{ return true; } - $rUsage = Utils::getRealMemoryUsage(); - $mUsage = Utils::getMemoryUsage(true); + $rUsage = Process::getRealMemoryUsage(); + $mUsage = Process::getMemoryUsage(true); $server = $sender->getServer(); $sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----"); @@ -94,7 +94,7 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($server->getNetwork()->getUpload() / 1024, 2) . " kB/s"); $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($server->getNetwork()->getDownload() / 1024, 2) . " kB/s"); - $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Utils::getThreadCount()); + $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Process::getThreadCount()); $sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB."); $sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB."); diff --git a/src/pocketmine/event/server/LowMemoryEvent.php b/src/pocketmine/event/server/LowMemoryEvent.php index 5e7412b1f..aaaaded62 100644 --- a/src/pocketmine/event/server/LowMemoryEvent.php +++ b/src/pocketmine/event/server/LowMemoryEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\utils\Utils; +use pocketmine\utils\Process; /** @@ -87,6 +87,6 @@ class LowMemoryEvent extends ServerEvent{ * @return int */ public function getMemoryFreed() : int{ - return $this->getMemory() - ($this->isGlobal() ? Utils::getMemoryUsage(true)[1] : Utils::getMemoryUsage(true)[0]); + return $this->getMemory() - ($this->isGlobal() ? Process::getMemoryUsage(true)[1] : Process::getMemoryUsage(true)[0]); } } diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index 7edd523f7..a566364a9 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -26,6 +26,7 @@ namespace pocketmine\scheduler; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\Server; use pocketmine\utils\Internet; +use pocketmine\utils\Process; use pocketmine\utils\Utils; use pocketmine\utils\UUID; use pocketmine\utils\VersionString; @@ -135,12 +136,12 @@ class SendUsageTask extends AsyncTask{ "historyList" => array_values($playerList) ]; - $info = Utils::getMemoryUsage(true); + $info = Process::getMemoryUsage(true); $data["system"] = [ "mainMemory" => $info[0], "totalMemory" => $info[1], "availableMemory" => $info[2], - "threadCount" => Utils::getThreadCount() + "threadCount" => Process::getThreadCount() ]; break; diff --git a/src/pocketmine/utils/Process.php b/src/pocketmine/utils/Process.php new file mode 100644 index 000000000..f5df0f703 --- /dev/null +++ b/src/pocketmine/utils/Process.php @@ -0,0 +1,170 @@ + 0){ + $VmRSS = $matches[1] * 1024; + } + + if(preg_match("/VmSize:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ + $VmSize = $matches[1] * 1024; + } + } + + //TODO: more OS + + if($VmRSS === null){ + $VmRSS = memory_get_usage(); + } + + if(!$advanced){ + return $VmRSS; + } + + if($VmSize === null){ + $VmSize = memory_get_usage(true); + } + + return [$reserved, $VmRSS, $VmSize]; + } + + /** + * @return int[] + */ + public static function getRealMemoryUsage() : array{ + $stack = 0; + $heap = 0; + + if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ + $mappings = file("/proc/self/maps"); + foreach($mappings as $line){ + if(preg_match("#([a-z0-9]+)\\-([a-z0-9]+) [rwxp\\-]{4} [a-z0-9]+ [^\\[]*\\[([a-zA-z0-9]+)\\]#", trim($line), $matches) > 0){ + if(strpos($matches[3], "heap") === 0){ + $heap += hexdec($matches[2]) - hexdec($matches[1]); + }elseif(strpos($matches[3], "stack") === 0){ + $stack += hexdec($matches[2]) - hexdec($matches[1]); + } + } + } + } + + return [$heap, $stack]; + } + + + public static function getThreadCount() : int{ + if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ + if(preg_match("/Threads:[ \t]+([0-9]+)/", file_get_contents("/proc/self/status"), $matches) > 0){ + return (int) $matches[1]; + } + } + + //TODO: more OS + + return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread + } + + public static function kill($pid) : void{ + if(MainLogger::isRegisteredStatic()){ + MainLogger::getLogger()->syncFlushBuffer(); + } + switch(Utils::getOS()){ + case "win": + exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL"); + break; + case "mac": + case "linux": + default: + if(function_exists("posix_kill")){ + posix_kill($pid, 9); //SIGKILL + }else{ + exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); + } + } + } + + /** + * @param string $command Command to execute + * @param string|null &$stdout Reference parameter to write stdout to + * @param string|null &$stderr Reference parameter to write stderr to + * + * @return int process exit code + */ + public static function execute(string $command, string &$stdout = null, string &$stderr = null) : int{ + $process = proc_open($command, [ + ["pipe", "r"], + ["pipe", "w"], + ["pipe", "w"] + ], $pipes); + + if($process === false){ + $stderr = "Failed to open process"; + $stdout = ""; + + return -1; + } + + $stdout = stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + + foreach($pipes as $p){ + fclose($p); + } + + return proc_close($process); + } +} diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index ff3ecd448..539f00af8 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -48,7 +48,7 @@ class ServerKiller extends Thread{ }); if(time() - $start >= $this->time){ echo "\nTook too long to stop, server was killed forcefully!\n"; - @Utils::kill(getmypid()); + @Process::kill(getmypid()); } } diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index a2fdf85a0..d4d89f1e5 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -28,7 +28,6 @@ declare(strict_types=1); namespace pocketmine\utils; use DaveRandom\CallbackValidator\CallbackType; -use pocketmine\ThreadManager; use function array_combine; use function array_map; use function array_reverse; @@ -42,7 +41,6 @@ use function dechex; use function error_reporting; use function exec; use function explode; -use function fclose; use function file; use function file_exists; use function file_get_contents; @@ -51,7 +49,6 @@ use function get_current_user; use function get_loaded_extensions; use function getenv; use function gettype; -use function hexdec; use function implode; use function is_array; use function is_dir; @@ -60,20 +57,16 @@ use function is_object; use function is_readable; use function is_string; use function json_decode; -use function memory_get_usage; use function ob_end_clean; use function ob_get_contents; use function ob_start; use function ord; use function php_uname; use function phpversion; -use function posix_kill; use function preg_grep; use function preg_match; use function preg_match_all; use function preg_replace; -use function proc_close; -use function proc_open; use function rmdir; use function scandir; use function sha1; @@ -81,7 +74,6 @@ use function spl_object_hash; use function str_pad; use function str_replace; use function str_split; -use function stream_get_contents; use function stripos; use function strlen; use function strpos; @@ -289,74 +281,35 @@ class Utils{ } /** + * @deprecated + * @see Process::getRealMemoryUsage() + * * @return int[] */ public static function getRealMemoryUsage() : array{ - $stack = 0; - $heap = 0; - - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - $mappings = file("/proc/self/maps"); - foreach($mappings as $line){ - if(preg_match("#([a-z0-9]+)\\-([a-z0-9]+) [rwxp\\-]{4} [a-z0-9]+ [^\\[]*\\[([a-zA-z0-9]+)\\]#", trim($line), $matches) > 0){ - if(strpos($matches[3], "heap") === 0){ - $heap += hexdec($matches[2]) - hexdec($matches[1]); - }elseif(strpos($matches[3], "stack") === 0){ - $stack += hexdec($matches[2]) - hexdec($matches[1]); - } - } - } - } - - return [$heap, $stack]; + return Process::getRealMemoryUsage(); } /** + * @deprecated + * @see Process::getMemoryUsage() + * * @param bool $advanced * * @return int[]|int */ public static function getMemoryUsage(bool $advanced = false){ - $reserved = memory_get_usage(); - $VmSize = null; - $VmRSS = null; - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - $status = file_get_contents("/proc/self/status"); - if(preg_match("/VmRSS:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ - $VmRSS = $matches[1] * 1024; - } - - if(preg_match("/VmSize:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ - $VmSize = $matches[1] * 1024; - } - } - - //TODO: more OS - - if($VmRSS === null){ - $VmRSS = memory_get_usage(); - } - - if(!$advanced){ - return $VmRSS; - } - - if($VmSize === null){ - $VmSize = memory_get_usage(true); - } - - return [$reserved, $VmRSS, $VmSize]; + return Process::getMemoryUsage($advanced); } + /** + * @deprecated + * @see Process::getThreadCount() + * + * @return int + */ public static function getThreadCount() : int{ - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - if(preg_match("/Threads:[ \t]+([0-9]+)/", file_get_contents("/proc/self/status"), $matches) > 0){ - return (int) $matches[1]; - } - } - //TODO: more OS - - return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread + return Process::getThreadCount(); } /** @@ -520,6 +473,9 @@ class Utils{ /** + * @deprecated + * @see Process::execute() + * * @param string $command Command to execute * @param string|null &$stdout Reference parameter to write stdout to * @param string|null &$stderr Reference parameter to write stderr to @@ -527,27 +483,7 @@ class Utils{ * @return int process exit code */ public static function execute(string $command, string &$stdout = null, string &$stderr = null) : int{ - $process = proc_open($command, [ - ["pipe", "r"], - ["pipe", "w"], - ["pipe", "w"] - ], $pipes); - - if($process === false){ - $stderr = "Failed to open process"; - $stdout = ""; - - return -1; - } - - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - - foreach($pipes as $p){ - fclose($p); - } - - return proc_close($process); + return Process::execute($command, $stdout, $stderr); } public static function decodeJWT(string $token) : array{ @@ -556,23 +492,14 @@ class Utils{ return json_decode(base64_decode(strtr($payloadB64, '-_', '+/'), true), true); } + /** + * @deprecated + * @see Process::kill() + * + * @param int $pid + */ public static function kill($pid) : void{ - if(MainLogger::isRegisteredStatic()){ - MainLogger::getLogger()->syncFlushBuffer(); - } - switch(Utils::getOS()){ - case "win": - exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL"); - break; - case "mac": - case "linux": - default: - if(function_exists("posix_kill")){ - posix_kill($pid, 9); //SIGKILL - }else{ - exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); - } - } + Process::kill($pid); } /** From 82e4ef6d4867c610b0e871c246333576630063f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 15:39:06 +0000 Subject: [PATCH 12/13] backport d8c81c0a1: UUID: remove useless default values these are overwritten by the constructor, so they have no use here. --- src/pocketmine/utils/UUID.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index 0c21d8a7b..b645000d1 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -38,8 +38,8 @@ use function trim; class UUID{ - private $parts = [0, 0, 0, 0]; - private $version = null; + private $parts; + private $version; public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, int $version = null){ $this->parts = [$part1, $part2, $part3, $part4]; From dbf4054b1fb2f01b1bc644747c94226a33012490 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 15:39:41 +0000 Subject: [PATCH 13/13] backport 209135492: UUID: add type docs --- src/pocketmine/utils/UUID.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index b645000d1..21432ad1f 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -38,7 +38,9 @@ use function trim; class UUID{ + /** @var int[] */ private $parts; + /** @var int */ private $version; public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, int $version = null){