diff --git a/build/php b/build/php index 46604f2f6..ed0bc4d2a 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 46604f2f6a07e3f68a82e4f4d7efdd45629b101e +Subproject commit ed0bc4d2afafd00f9ee92823c6b1bd66789ce4f2 diff --git a/composer.json b/composer.json index f191086ca..5a875d218 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", - "ext-pmmpthread": "^6.0.4", + "ext-pmmpthread": "^6.0.7", "ext-reflection": "*", "ext-simplexml": "*", "ext-sockets": "*", diff --git a/composer.lock b/composer.lock index 40bdcb23d..de7ccf126 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "63ecdcea88960659a6977300a0ea79b3", + "content-hash": "2d51c1adf069760587b6d36f9c4a5db3", "packages": [ { "name": "adhocore/json-comment", @@ -1861,16 +1861,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.2.7", + "version": "10.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a215d9ee8bac1733796e4ddff3306811f14414e5" + "reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a215d9ee8bac1733796e4ddff3306811f14414e5", - "reference": "a215d9ee8bac1733796e4ddff3306811f14414e5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d442ce7c4104d5683c12e67e4dcb5058159e9804", + "reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804", "shasum": "" }, "require": { @@ -1910,7 +1910,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.2-dev" + "dev-main": "10.3-dev" } }, "autoload": { @@ -1942,7 +1942,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.7" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.1" }, "funding": [ { @@ -1958,7 +1958,7 @@ "type": "tidelift" } ], - "time": "2023-08-02T06:46:08+00:00" + "time": "2023-08-04T06:48:08+00:00" }, { "name": "sebastian/cli-parser", @@ -2945,7 +2945,7 @@ "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", - "ext-pmmpthread": "^6.0.4", + "ext-pmmpthread": "^6.0.7", "ext-reflection": "*", "ext-simplexml": "*", "ext-sockets": "*", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b3aeaf4f6..1d72511f7 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -11,6 +11,7 @@ includes: rules: - pocketmine\phpstan\rules\DisallowEnumComparisonRule + - pocketmine\phpstan\rules\DisallowForeachByReferenceRule - pocketmine\phpstan\rules\UnsafeForeachArrayOfStringRule # - pocketmine\phpstan\rules\ThreadedSupportedTypesRule diff --git a/src/PocketMine.php b/src/PocketMine.php index 2c8ab06de..4c2ff32a7 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -120,8 +120,8 @@ namespace pocketmine { } if(($pmmpthread_version = phpversion("pmmpthread")) !== false){ - if(version_compare($pmmpthread_version, "6.0.4") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){ - $messages[] = "pmmpthread ^6.0.4 is required, while you have $pmmpthread_version."; + if(version_compare($pmmpthread_version, "6.0.7") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){ + $messages[] = "pmmpthread ^6.0.7 is required, while you have $pmmpthread_version."; } } diff --git a/src/block/Podzol.php b/src/block/Podzol.php index 4eb720573..33285cc0e 100644 --- a/src/block/Podzol.php +++ b/src/block/Podzol.php @@ -27,6 +27,10 @@ use pocketmine\item\Item; class Podzol extends Opaque{ + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaBlocks::DIRT()->asItem() diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index e59b6971f..e2d6d9a66 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -85,6 +85,7 @@ class RakLibServer extends Thread{ gc_enable(); ini_set("display_errors", '1'); ini_set("display_startup_errors", '1'); + \GlobalLogger::set($this->logger); $socket = new ServerSocket($this->address->deserialize()); $manager = new Server( @@ -107,11 +108,6 @@ class RakLibServer extends Thread{ $manager->waitShutdown(); } - protected function onUncaughtException(\Throwable $e) : void{ - parent::onUncaughtException($e); - $this->logger->logException($e); - } - public function getThreadName() : string{ return "RakLib"; } diff --git a/src/permission/PermissionManager.php b/src/permission/PermissionManager.php index b7e622934..2d8324887 100644 --- a/src/permission/PermissionManager.php +++ b/src/permission/PermissionManager.php @@ -81,9 +81,9 @@ class PermissionManager{ } public function unsubscribeFromAllPermissions(PermissibleInternal $permissible) : void{ - foreach($this->permSubs as $permission => &$subs){ - unset($subs[spl_object_id($permissible)]); - if(count($subs) === 0){ + foreach($this->permSubs as $permission => $subs){ + unset($this->permSubs[$permission][spl_object_id($permissible)]); + if(count($this->permSubs[$permission]) === 0){ unset($this->permSubs[$permission]); } } diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index b26afc29b..919e3eedc 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -69,11 +69,6 @@ class AsyncWorker extends Worker{ $this->saveToThreadStore(self::TLS_KEY_NOTIFIER, $this->sleeperEntry->createNotifier()); } - protected function onUncaughtException(\Throwable $e) : void{ - parent::onUncaughtException($e); - $this->logger->logException($e); - } - public function getLogger() : ThreadSafeLogger{ return $this->logger; } diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index 340ce554d..de2ecbde8 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -28,6 +28,7 @@ use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\Server; use function error_get_last; use function error_reporting; +use function implode; use function register_shutdown_function; use function set_exception_handler; @@ -115,6 +116,7 @@ trait CommonThreadPartsTrait{ protected function onUncaughtException(\Throwable $e) : void{ $this->synchronized(function() use ($e) : void{ $this->crashInfo = ThreadCrashInfo::fromThrowable($e, $this->getThreadName()); + \GlobalLogger::get()->logException($e); }); } @@ -124,15 +126,26 @@ trait CommonThreadPartsTrait{ */ protected function onShutdown() : void{ $this->synchronized(function() : void{ - if(!$this->isKilled && $this->crashInfo === null){ + if($this->isTerminated() && $this->crashInfo === null){ $last = error_get_last(); if($last !== null){ //fatal error - $this->crashInfo = ThreadCrashInfo::fromLastErrorInfo($last, $this->getThreadName()); + $crashInfo = ThreadCrashInfo::fromLastErrorInfo($last, $this->getThreadName()); }else{ //probably misused exit() - $this->crashInfo = ThreadCrashInfo::fromThrowable(new \RuntimeException("Thread crashed without an error - perhaps exit() was called?"), $this->getThreadName()); + $crashInfo = ThreadCrashInfo::fromThrowable(new \RuntimeException("Thread crashed without an error - perhaps exit() was called?"), $this->getThreadName()); } + $this->crashInfo = $crashInfo; + + $lines = []; + //mimic exception printed format + $lines[] = "Fatal error: " . $crashInfo->makePrettyMessage(); + $lines[] = "--- Stack trace ---"; + foreach($crashInfo->getTrace() as $frame){ + $lines[] = " " . $frame->getPrintableFrame(); + } + $lines[] = "--- End of fatal error information ---"; + \GlobalLogger::get()->critical(implode("\n", $lines)); } }); } diff --git a/src/world/World.php b/src/world/World.php index 4d6cad154..7d9311c70 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -3003,7 +3003,7 @@ class World implements ChunkManager{ * @throws WorldException if the terrain is not generated */ public function getSafeSpawn(?Vector3 $spawn = null) : Position{ - if(!($spawn instanceof Vector3) || $spawn->y < 1){ + if(!($spawn instanceof Vector3) || $spawn->y <= $this->minY){ $spawn = $this->getSpawnLocation(); } diff --git a/tests/phpstan/rules/DisallowForeachByReferenceRule.php b/tests/phpstan/rules/DisallowForeachByReferenceRule.php new file mode 100644 index 000000000..79124d328 --- /dev/null +++ b/tests/phpstan/rules/DisallowForeachByReferenceRule.php @@ -0,0 +1,53 @@ + + */ +final class DisallowForeachByReferenceRule implements Rule{ + + public function getNodeType() : string{ + return Foreach_::class; + } + + public function processNode(Node $node, Scope $scope) : array{ + /** @var Foreach_ $node */ + if($node->byRef){ + return [ + RuleErrorBuilder::message("Foreach by-reference is not allowed, because it has surprising behaviour.") + ->tip("If the value variable is used outside of the foreach construct (e.g. in a second foreach), the iterable's contents will be unexpectedly altered.") + ->build() + ]; + } + + return []; + } +} diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 9930c54f0..ac8a1ad9d 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -24,6 +24,7 @@ declare(strict_types=1); use pocketmine\block\Block; use pocketmine\block\RuntimeBlockStateRegistry; use pocketmine\utils\AssumptionFailedError; +use pocketmine\utils\Utils; require dirname(__DIR__, 3) . '/vendor/autoload.php'; @@ -91,8 +92,9 @@ foreach($new as $stateId => $name){ $newTable[$name][] = $stateId; } ksort($newTable, SORT_STRING); -foreach($newTable as &$stateIds){ +foreach(Utils::stringifyKeys($newTable) as $name => $stateIds){ sort($stateIds, SORT_NUMERIC); + $newTable[$name] = $stateIds; } file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode(