From 3a5fc78c53ed8b31a28607f2e1b23efce3cdb39a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 17:47:48 +0100 Subject: [PATCH 1/6] Fixed players getting kicked for flying when standing still when blocks near them get updated, fixed item movement being too slippery --- src/pocketmine/entity/Entity.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7f880ecf79..a6afc6e1cb 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1208,18 +1208,18 @@ abstract class Entity extends Location implements Metadatable{ protected function tryChangeMovement(){ $friction = 1 - $this->drag; - if(!$this->onGround){ - if($this->applyDragBeforeGravity()){ - $this->motionY *= $friction; - } + if($this->applyDragBeforeGravity()){ + $this->motionY *= $friction; + } - $this->applyGravity(); + $this->applyGravity(); - if(!$this->applyDragBeforeGravity()){ - $this->motionY *= $friction; - } - }else{ - $friction = $this->level->getBlock($this->floor()->subtract(0, 1, 0))->getFrictionFactor(); + if(!$this->applyDragBeforeGravity()){ + $this->motionY *= $friction; + } + + if($this->onGround){ + $friction *= $this->level->getBlock($this->floor()->subtract(0, 1, 0))->getFrictionFactor(); } $this->motionX *= $friction; @@ -1311,7 +1311,6 @@ abstract class Entity extends Location implements Metadatable{ */ final public function setForceMovementUpdate(bool $value = true){ $this->forceMovementUpdate = $value; - $this->onGround = false; $this->blocksAround = null; } From ae715cf2f2495e8c102d0958fa1848ad8805c9df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 17:54:45 +0100 Subject: [PATCH 2/6] Updated RakLib submodule --- src/raklib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raklib b/src/raklib index 05419714c3..634dd5c965 160000 --- a/src/raklib +++ b/src/raklib @@ -1 +1 @@ -Subproject commit 05419714c36c10db86edaa0c7049a9f054e4a3b4 +Subproject commit 634dd5c9656cad220c8fb4fefc82e19c24b20c5b From 0712979908cf97ad552ddec62ca7be863f8bc564 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 19:45:53 +0100 Subject: [PATCH 3/6] Fixed blastResistance array not being initialized --- src/pocketmine/block/BlockFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f00d8e15f0..a6bf9472ce 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -65,6 +65,7 @@ class BlockFactory{ self::$hardness = new \SplFixedArray(256); self::$transparent = new \SplFixedArray(256); self::$diffusesSkyLight = new \SplFixedArray(256); + self::$blastResistance = new \SplFixedArray(256); self::registerBlock(new Air()); self::registerBlock(new Stone()); From 5a3ce42f74d3ce166ed0a4fbb2e6d320730699b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 19:55:47 +0100 Subject: [PATCH 4/6] Updated RakLib submodule (again) --- src/raklib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raklib b/src/raklib index 634dd5c965..3b1ca9c1be 160000 --- a/src/raklib +++ b/src/raklib @@ -1 +1 @@ -Subproject commit 634dd5c9656cad220c8fb4fefc82e19c24b20c5b +Subproject commit 3b1ca9c1bedf1a18ef40757665bf8c9e7e769c9c From eb4594348b6fe4f8af83d5fd386f393956f7b561 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 19:57:00 +0100 Subject: [PATCH 5/6] Added capability to dump AsyncWorker memory --- src/pocketmine/MemoryManager.php | 73 +++++++++++++++---- src/pocketmine/scheduler/AsyncWorker.php | 4 + .../scheduler/DumpWorkerMemoryTask.php | 59 +++++++++++++++ 3 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 src/pocketmine/scheduler/DumpWorkerMemoryTask.php diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 355bcf38f6..ef187a2eeb 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -25,7 +25,9 @@ namespace pocketmine; use pocketmine\event\server\LowMemoryEvent; use pocketmine\event\Timings; +use pocketmine\scheduler\DumpWorkerMemoryTask; use pocketmine\scheduler\GarbageCollectionTask; +use pocketmine\utils\MainLogger; use pocketmine\utils\Utils; class MemoryManager{ @@ -261,6 +263,25 @@ class MemoryManager{ * @param int $maxStringSize */ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){ + MainLogger::getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); + self::dumpMemory($this->server, $this->server->getLoader(), $outputFolder, $maxNesting, $maxStringSize); + + $scheduler = $this->server->getScheduler(); + for($i = 0, $size = $scheduler->getAsyncTaskPoolSize(); $i < $size; ++$i){ + $scheduler->scheduleAsyncTaskToWorker(new DumpWorkerMemoryTask($outputFolder, $maxNesting, $maxStringSize), $i); + } + } + + /** + * Static memory dumper accessible from any thread. + * + * @param mixed $startingObject + * @param \ClassLoader $loader + * @param string $outputFolder + * @param int $maxNesting + * @param int $maxStringSize + */ + public static function dumpMemory($startingObject, \ClassLoader $loader, string $outputFolder, int $maxNesting, int $maxStringSize){ $hardLimit = ini_get('memory_limit'); ini_set('memory_limit', '-1'); gc_disable(); @@ -269,12 +290,8 @@ class MemoryManager{ mkdir($outputFolder, 0777, true); } - $this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); - $obData = fopen($outputFolder . "/objects.js", "wb+"); - $staticProperties = []; - $data = []; $objects = []; @@ -283,8 +300,9 @@ class MemoryManager{ $instanceCounts = []; + $staticProperties = []; $staticCount = 0; - foreach($this->server->getLoader()->getClasses() as $className){ + foreach($loader->getClasses() as $className){ $reflection = new \ReflectionClass($className); $staticProperties[$className] = []; foreach($reflection->getProperties() as $property){ @@ -297,7 +315,7 @@ class MemoryManager{ } $staticCount++; - $this->continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); } if(count($staticProperties[$className]) === 0){ @@ -305,9 +323,37 @@ class MemoryManager{ } } - echo "[Dump] Wrote $staticCount static properties\n"; + file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + MainLogger::getLogger()->info("[Dump] Wrote $staticCount static properties"); - $this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $globalVariables = []; + + $ignoredGlobals = [ + 'GLOBALS' => true, + '_SERVER' => true, + '_REQUEST' => true, + '_POST' => true, + '_GET' => true, + '_FILES' => true, + '_ENV' => true, + '_COOKIE' => true, + '_SESSION' => true + ]; + + $globalCount = 0; + foreach($GLOBALS as $varName => $value){ + if(isset($ignoredGlobals[$varName])){ + continue; + } + + $globalCount++; + self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + } + + file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + MainLogger::getLogger()->info("[Dump] Wrote $globalCount global variables"); + + self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); do{ $continue = false; @@ -349,25 +395,24 @@ class MemoryManager{ if(!$property->isPublic()){ $property->setAccessible(true); } - $this->continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + self::continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); } fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); } - echo "[Dump] Wrote " . count($objects) . " objects\n"; + MainLogger::getLogger()->info("[Dump] Wrote " . count($objects) . " objects"); }while($continue); fclose($obData); - file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); arsort($instanceCounts, SORT_NUMERIC); file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - echo "[Dump] Finished!\n"; + MainLogger::getLogger()->info("[Dump] Finished!"); ini_set('memory_limit', $hardLimit); gc_enable(); @@ -382,7 +427,7 @@ class MemoryManager{ * @param int $maxNesting * @param int $maxStringSize */ - private function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ + private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ if($maxNesting <= 0){ $data = "(error) NESTING LIMIT REACHED"; return; @@ -406,7 +451,7 @@ class MemoryManager{ } $data = []; foreach($from as $key => $value){ - $this->continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); + self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); } }elseif(is_string($from)){ $data = "(string) len(". strlen($from) .") " . substr(Utils::printable($from), 0, $maxStringSize); diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 80608acda1..57d41d5c12 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -64,4 +64,8 @@ class AsyncWorker extends Worker{ public function getThreadName() : string{ return "Asynchronous Worker #" . $this->id; } + + public function getAsyncWorkerId() : int{ + return $this->id; + } } diff --git a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php new file mode 100644 index 0000000000..8146625b1f --- /dev/null +++ b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php @@ -0,0 +1,59 @@ +outputFolder = $outputFolder; + $this->maxNesting = $maxNesting; + $this->maxStringSize = $maxStringSize; + } + + public function onRun(){ + MemoryManager::dumpMemory( + $this->worker, + $this->worker->getClassLoader(), + $this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(), + $this->maxNesting, + $this->maxStringSize + ); + } +} \ No newline at end of file From d1852834de3e69b54b790ae928371640c205c614 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Aug 2017 20:46:20 +0100 Subject: [PATCH 6/6] Revert "Added capability to dump AsyncWorker memory" This reverts commit eb4594348b6fe4f8af83d5fd386f393956f7b561. This is far too unstable with more than one worker thread. --- src/pocketmine/MemoryManager.php | 73 ++++--------------- src/pocketmine/scheduler/AsyncWorker.php | 4 - .../scheduler/DumpWorkerMemoryTask.php | 59 --------------- 3 files changed, 14 insertions(+), 122 deletions(-) delete mode 100644 src/pocketmine/scheduler/DumpWorkerMemoryTask.php diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index ef187a2eeb..355bcf38f6 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -25,9 +25,7 @@ namespace pocketmine; use pocketmine\event\server\LowMemoryEvent; use pocketmine\event\Timings; -use pocketmine\scheduler\DumpWorkerMemoryTask; use pocketmine\scheduler\GarbageCollectionTask; -use pocketmine\utils\MainLogger; use pocketmine\utils\Utils; class MemoryManager{ @@ -263,25 +261,6 @@ class MemoryManager{ * @param int $maxStringSize */ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){ - MainLogger::getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); - self::dumpMemory($this->server, $this->server->getLoader(), $outputFolder, $maxNesting, $maxStringSize); - - $scheduler = $this->server->getScheduler(); - for($i = 0, $size = $scheduler->getAsyncTaskPoolSize(); $i < $size; ++$i){ - $scheduler->scheduleAsyncTaskToWorker(new DumpWorkerMemoryTask($outputFolder, $maxNesting, $maxStringSize), $i); - } - } - - /** - * Static memory dumper accessible from any thread. - * - * @param mixed $startingObject - * @param \ClassLoader $loader - * @param string $outputFolder - * @param int $maxNesting - * @param int $maxStringSize - */ - public static function dumpMemory($startingObject, \ClassLoader $loader, string $outputFolder, int $maxNesting, int $maxStringSize){ $hardLimit = ini_get('memory_limit'); ini_set('memory_limit', '-1'); gc_disable(); @@ -290,8 +269,12 @@ class MemoryManager{ mkdir($outputFolder, 0777, true); } + $this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); + $obData = fopen($outputFolder . "/objects.js", "wb+"); + $staticProperties = []; + $data = []; $objects = []; @@ -300,9 +283,8 @@ class MemoryManager{ $instanceCounts = []; - $staticProperties = []; $staticCount = 0; - foreach($loader->getClasses() as $className){ + foreach($this->server->getLoader()->getClasses() as $className){ $reflection = new \ReflectionClass($className); $staticProperties[$className] = []; foreach($reflection->getProperties() as $property){ @@ -315,7 +297,7 @@ class MemoryManager{ } $staticCount++; - self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $this->continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); } if(count($staticProperties[$className]) === 0){ @@ -323,37 +305,9 @@ class MemoryManager{ } } - file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - MainLogger::getLogger()->info("[Dump] Wrote $staticCount static properties"); + echo "[Dump] Wrote $staticCount static properties\n"; - $globalVariables = []; - - $ignoredGlobals = [ - 'GLOBALS' => true, - '_SERVER' => true, - '_REQUEST' => true, - '_POST' => true, - '_GET' => true, - '_FILES' => true, - '_ENV' => true, - '_COOKIE' => true, - '_SESSION' => true - ]; - - $globalCount = 0; - foreach($GLOBALS as $varName => $value){ - if(isset($ignoredGlobals[$varName])){ - continue; - } - - $globalCount++; - self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize); - } - - file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - MainLogger::getLogger()->info("[Dump] Wrote $globalCount global variables"); - - self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); do{ $continue = false; @@ -395,24 +349,25 @@ class MemoryManager{ if(!$property->isPublic()){ $property->setAccessible(true); } - self::continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $this->continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); } fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); } - MainLogger::getLogger()->info("[Dump] Wrote " . count($objects) . " objects"); + echo "[Dump] Wrote " . count($objects) . " objects\n"; }while($continue); fclose($obData); + file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); arsort($instanceCounts, SORT_NUMERIC); file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - MainLogger::getLogger()->info("[Dump] Finished!"); + echo "[Dump] Finished!\n"; ini_set('memory_limit', $hardLimit); gc_enable(); @@ -427,7 +382,7 @@ class MemoryManager{ * @param int $maxNesting * @param int $maxStringSize */ - private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ + private function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ if($maxNesting <= 0){ $data = "(error) NESTING LIMIT REACHED"; return; @@ -451,7 +406,7 @@ class MemoryManager{ } $data = []; foreach($from as $key => $value){ - self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); + $this->continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); } }elseif(is_string($from)){ $data = "(string) len(". strlen($from) .") " . substr(Utils::printable($from), 0, $maxStringSize); diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 57d41d5c12..80608acda1 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -64,8 +64,4 @@ class AsyncWorker extends Worker{ public function getThreadName() : string{ return "Asynchronous Worker #" . $this->id; } - - public function getAsyncWorkerId() : int{ - return $this->id; - } } diff --git a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php deleted file mode 100644 index 8146625b1f..0000000000 --- a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php +++ /dev/null @@ -1,59 +0,0 @@ -outputFolder = $outputFolder; - $this->maxNesting = $maxNesting; - $this->maxStringSize = $maxStringSize; - } - - public function onRun(){ - MemoryManager::dumpMemory( - $this->worker, - $this->worker->getClassLoader(), - $this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(), - $this->maxNesting, - $this->maxStringSize - ); - } -} \ No newline at end of file