Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor 2023-11-01 16:39:55 +00:00
commit 54694df48c
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
8 changed files with 55 additions and 43 deletions

View File

@ -18,3 +18,10 @@ Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if
## Fixes ## Fixes
- Fixed `cartography_table`, `smithing_table`, `stripped_cherry_log` and `stripped_cherry_wood` not working in `StringToItemParser`. - Fixed `cartography_table`, `smithing_table`, `stripped_cherry_log` and `stripped_cherry_wood` not working in `StringToItemParser`.
- Fixed `Promise<null>::onCompletion()` always calling the reject handler if the promise was already completed. - Fixed `Promise<null>::onCompletion()` always calling the reject handler if the promise was already completed.
# 5.7.1
Released 1st November 2023.
## Fixes
- Fixed non-reentrant-safe code in `PermissionManager` and various other subscriber subsystems.
- These issues caused server crashes when deleting a subscriber indirectly triggered the deletion of other subscribers (e.g. due to the GC activating in `unset()`).

View File

@ -52,7 +52,7 @@
"symfony/filesystem": "~6.3.0" "symfony/filesystem": "~6.3.0"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "1.10.39", "phpstan/phpstan": "1.10.40",
"phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0", "phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0" "phpunit/phpunit": "~10.3.0 || ~10.2.0 || ~10.1.0"

28
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "feefde772166966ee8065e613fe9a56e", "content-hash": "ca499c3c5acafac837f7384ecdae136e",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -1378,16 +1378,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.10.39", "version": "1.10.40",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4" "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/d9dedb0413f678b4d03cbc2279a48f91592c97c4", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/93c84b5bf7669920d823631e39904d69b9c7dc5d",
"reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4", "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1436,7 +1436,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-10-17T15:46:26+00:00" "time": "2023-10-30T14:48:31+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
@ -1492,21 +1492,21 @@
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
"version": "1.5.1", "version": "1.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git", "url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6" "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b21c03d4f6f3a446e4311155f4be9d65048218e6", "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542",
"reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6", "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2 || ^8.0", "php": "^7.2 || ^8.0",
"phpstan/phpstan": "^1.10" "phpstan/phpstan": "^1.10.34"
}, },
"require-dev": { "require-dev": {
"nikic/php-parser": "^4.13.0", "nikic/php-parser": "^4.13.0",
@ -1535,9 +1535,9 @@
"description": "Extra strict and opinionated rules for PHPStan", "description": "Extra strict and opinionated rules for PHPStan",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues", "issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.1" "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2"
}, },
"time": "2023-03-29T14:47:40+00:00" "time": "2023-10-30T14:35:06+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@ -2964,5 +2964,5 @@
"platform-overrides": { "platform-overrides": {
"php": "8.1.0" "php": "8.1.0"
}, },
"plugin-api-version": "2.6.0" "plugin-api-version": "2.3.0"
} }

View File

@ -1261,9 +1261,10 @@ class Server{
*/ */
public function unsubscribeFromBroadcastChannel(string $channelId, CommandSender $subscriber) : void{ public function unsubscribeFromBroadcastChannel(string $channelId, CommandSender $subscriber) : void{
if(isset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)])){ if(isset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)])){
unset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)]); if(count($this->broadcastSubscribers[$channelId]) === 1){
if(count($this->broadcastSubscribers[$channelId]) === 0){
unset($this->broadcastSubscribers[$channelId]); unset($this->broadcastSubscribers[$channelId]);
}else{
unset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)]);
} }
} }
} }

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{ final class VersionInfo{
public const NAME = "PocketMine-MP"; public const NAME = "PocketMine-MP";
public const BASE_VERSION = "5.7.1"; public const BASE_VERSION = "5.7.2";
public const IS_DEVELOPMENT_BUILD = true; public const IS_DEVELOPMENT_BUILD = true;
public const BUILD_CHANNEL = "stable"; public const BUILD_CHANNEL = "stable";

View File

@ -72,19 +72,21 @@ class PermissionManager{
} }
public function unsubscribeFromPermission(string $permission, PermissibleInternal $permissible) : void{ public function unsubscribeFromPermission(string $permission, PermissibleInternal $permissible) : void{
if(isset($this->permSubs[$permission])){ if(isset($this->permSubs[$permission][spl_object_id($permissible)])){
unset($this->permSubs[$permission][spl_object_id($permissible)]); if(count($this->permSubs[$permission]) === 1){
if(count($this->permSubs[$permission]) === 0){
unset($this->permSubs[$permission]); unset($this->permSubs[$permission]);
}else{
unset($this->permSubs[$permission][spl_object_id($permissible)]);
} }
} }
} }
public function unsubscribeFromAllPermissions(PermissibleInternal $permissible) : void{ public function unsubscribeFromAllPermissions(PermissibleInternal $permissible) : void{
foreach($this->permSubs as $permission => $subs){ foreach($this->permSubs as $permission => $subs){
unset($this->permSubs[$permission][spl_object_id($permissible)]); if(count($subs) === 1 && isset($subs[spl_object_id($permissible)])){
if(count($this->permSubs[$permission]) === 0){
unset($this->permSubs[$permission]); unset($this->permSubs[$permission]);
}else{
unset($this->permSubs[$permission][spl_object_id($permissible)]);
} }
} }
} }

View File

@ -508,9 +508,12 @@ class PluginManager{
unset($this->enabledPlugins[$plugin->getDescription()->getName()]); unset($this->enabledPlugins[$plugin->getDescription()->getName()]);
foreach(Utils::stringifyKeys($this->pluginDependents) as $dependency => $dependentList){ foreach(Utils::stringifyKeys($this->pluginDependents) as $dependency => $dependentList){
unset($this->pluginDependents[$dependency][$plugin->getDescription()->getName()]); if(isset($this->pluginDependents[$dependency][$plugin->getDescription()->getName()])){
if(count($this->pluginDependents[$dependency]) === 0){ if(count($this->pluginDependents[$dependency]) === 1){
unset($this->pluginDependents[$dependency]); unset($this->pluginDependents[$dependency]);
}else{
unset($this->pluginDependents[$dependency][$plugin->getDescription()->getName()]);
}
} }
} }

View File

@ -826,14 +826,15 @@ class World implements ChunkManager{
$chunkHash = World::chunkHash($chunkX, $chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ);
$loaderId = spl_object_id($loader); $loaderId = spl_object_id($loader);
if(isset($this->chunkLoaders[$chunkHash][$loaderId])){ if(isset($this->chunkLoaders[$chunkHash][$loaderId])){
unset($this->chunkLoaders[$chunkHash][$loaderId]); if(count($this->chunkLoaders[$chunkHash]) === 1){
if(count($this->chunkLoaders[$chunkHash]) === 0){
unset($this->chunkLoaders[$chunkHash]); unset($this->chunkLoaders[$chunkHash]);
$this->unloadChunkRequest($chunkX, $chunkZ, true); $this->unloadChunkRequest($chunkX, $chunkZ, true);
if(isset($this->chunkPopulationRequestMap[$chunkHash]) && !isset($this->activeChunkPopulationTasks[$chunkHash])){ if(isset($this->chunkPopulationRequestMap[$chunkHash]) && !isset($this->activeChunkPopulationTasks[$chunkHash])){
$this->chunkPopulationRequestMap[$chunkHash]->reject(); $this->chunkPopulationRequestMap[$chunkHash]->reject();
unset($this->chunkPopulationRequestMap[$chunkHash]); unset($this->chunkPopulationRequestMap[$chunkHash]);
} }
}else{
unset($this->chunkLoaders[$chunkHash][$loaderId]);
} }
} }
} }
@ -861,11 +862,12 @@ class World implements ChunkManager{
public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{
$hash = World::chunkHash($chunkX, $chunkZ); $hash = World::chunkHash($chunkX, $chunkZ);
if(isset($this->chunkListeners[$hash])){ if(isset($this->chunkListeners[$hash])){
unset($this->chunkListeners[$hash][spl_object_id($listener)]); if(count($this->chunkListeners[$hash]) === 1){
unset($this->playerChunkListeners[$hash][spl_object_id($listener)]);
if(count($this->chunkListeners[$hash]) === 0){
unset($this->chunkListeners[$hash]); unset($this->chunkListeners[$hash]);
unset($this->playerChunkListeners[$hash]); unset($this->playerChunkListeners[$hash]);
}else{
unset($this->chunkListeners[$hash][spl_object_id($listener)]);
unset($this->playerChunkListeners[$hash][spl_object_id($listener)]);
} }
} }
} }
@ -1219,13 +1221,14 @@ class World implements ChunkManager{
$chunkHash = World::chunkHash($chunkX, $chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ);
$tickerId = spl_object_id($ticker); $tickerId = spl_object_id($ticker);
if(isset($this->registeredTickingChunks[$chunkHash][$tickerId])){ if(isset($this->registeredTickingChunks[$chunkHash][$tickerId])){
unset($this->registeredTickingChunks[$chunkHash][$tickerId]); if(count($this->registeredTickingChunks[$chunkHash]) === 1){
if(count($this->registeredTickingChunks[$chunkHash]) === 0){
unset( unset(
$this->registeredTickingChunks[$chunkHash], $this->registeredTickingChunks[$chunkHash],
$this->recheckTickingChunks[$chunkHash], $this->recheckTickingChunks[$chunkHash],
$this->validTickingChunks[$chunkHash] $this->validTickingChunks[$chunkHash]
); );
}else{
unset($this->registeredTickingChunks[$chunkHash][$tickerId]);
} }
} }
} }
@ -2292,9 +2295,6 @@ class World implements ChunkManager{
for($x = $minX; $x <= $maxX; ++$x){ for($x = $minX; $x <= $maxX; ++$x){
for($z = $minZ; $z <= $maxZ; ++$z){ for($z = $minZ; $z <= $maxZ; ++$z){
if(!$this->isChunkLoaded($x, $z)){
continue;
}
foreach($this->getChunkEntities($x, $z) as $ent){ foreach($this->getChunkEntities($x, $z) as $ent){
if($ent !== $entity && $ent->boundingBox->intersectsWith($bb)){ if($ent !== $entity && $ent->boundingBox->intersectsWith($bb)){
$nearby[] = $ent; $nearby[] = $ent;
@ -2335,9 +2335,6 @@ class World implements ChunkManager{
for($x = $minX; $x <= $maxX; ++$x){ for($x = $minX; $x <= $maxX; ++$x){
for($z = $minZ; $z <= $maxZ; ++$z){ for($z = $minZ; $z <= $maxZ; ++$z){
if(!$this->isChunkLoaded($x, $z)){
continue;
}
foreach($this->getChunkEntities($x, $z) as $entity){ foreach($this->getChunkEntities($x, $z) as $entity){
if(!($entity instanceof $entityType) || $entity->isFlaggedForDespawn() || (!$includeDead && !$entity->isAlive())){ if(!($entity instanceof $entityType) || $entity->isFlaggedForDespawn() || (!$includeDead && !$entity->isAlive())){
continue; continue;
@ -2664,9 +2661,10 @@ class World implements ChunkManager{
$pos = $this->entityLastKnownPositions[$entity->getId()]; $pos = $this->entityLastKnownPositions[$entity->getId()];
$chunkHash = World::chunkHash($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE); $chunkHash = World::chunkHash($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE);
if(isset($this->entitiesByChunk[$chunkHash][$entity->getId()])){ if(isset($this->entitiesByChunk[$chunkHash][$entity->getId()])){
unset($this->entitiesByChunk[$chunkHash][$entity->getId()]); if(count($this->entitiesByChunk[$chunkHash]) === 1){
if(count($this->entitiesByChunk[$chunkHash]) === 0){
unset($this->entitiesByChunk[$chunkHash]); unset($this->entitiesByChunk[$chunkHash]);
}else{
unset($this->entitiesByChunk[$chunkHash][$entity->getId()]);
} }
} }
unset($this->entityLastKnownPositions[$entity->getId()]); unset($this->entityLastKnownPositions[$entity->getId()]);
@ -2699,9 +2697,10 @@ class World implements ChunkManager{
if($oldChunkX !== $newChunkX || $oldChunkZ !== $newChunkZ){ if($oldChunkX !== $newChunkX || $oldChunkZ !== $newChunkZ){
$oldChunkHash = World::chunkHash($oldChunkX, $oldChunkZ); $oldChunkHash = World::chunkHash($oldChunkX, $oldChunkZ);
if(isset($this->entitiesByChunk[$oldChunkHash][$entity->getId()])){ if(isset($this->entitiesByChunk[$oldChunkHash][$entity->getId()])){
unset($this->entitiesByChunk[$oldChunkHash][$entity->getId()]); if(count($this->entitiesByChunk[$oldChunkHash]) === 1){
if(count($this->entitiesByChunk[$oldChunkHash]) === 0){
unset($this->entitiesByChunk[$oldChunkHash]); unset($this->entitiesByChunk[$oldChunkHash]);
}else{
unset($this->entitiesByChunk[$oldChunkHash][$entity->getId()]);
} }
} }