Compare commits

..

6 Commits

Author SHA1 Message Date
1e797b9897 Prepare 5.33.2 release (#6804) 2025-09-15 23:53:05 +01:00
a056af1617 Update composer dev dependencies 2025-09-15 22:41:02 +01:00
b237cacfc9 InGamePacketHandler: don't resync blocks if the client predicted an interact fail
if the prediction was a fail, we can assume that the client didn't do anything visual on its end,
which avoids the need to resend blocks.
This fixes block lag when towering as discussed in #6803.

The more general issue in #6803 remains unresolved (that the server's block resyncing may overwrite
additional client side predictions if it places a block before the server's resync for the initial
placement arrives), but that's more complicated to fix and I'm not convinced on the correct method
to resolve it yet.

In any case, this change nets a decent improvement for everyone, regardless.
2025-09-15 19:36:29 +01:00
e7ad3c25fa InGamePacketHandler: ignore CREATIVE_PLAYER_DESTROY_BLOCK
fixes #6757

we get PREDICT_DESTROY_BLOCK anyway, so it's not needed
2025-09-15 18:02:10 +01:00
c6a28d8df0 InventoryManager: fixed window sending getting stuck on client rejecting window opening
closes #6778

honestly, we could just stop checking the window ID entirely, considering the need for delaying and waiting
for window close acks, it seems useless at this point...
2025-09-15 17:34:35 +01:00
636b96a9a5 Updated composer dependencies 2025-09-12 01:13:55 +01:00
14 changed files with 131 additions and 64 deletions

View File

@ -29,6 +29,9 @@ use pocketmine\data\bedrock\block\BlockStateStringValues;
use pocketmine\data\bedrock\block\BlockTypeNames; use pocketmine\data\bedrock\block\BlockTypeNames;
use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\errorhandler\ErrorToExceptionHandler;
use pocketmine\nbt\NbtException; use pocketmine\nbt\NbtException;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\convert\BlockStateDictionary; use pocketmine\network\mcpe\convert\BlockStateDictionary;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
@ -78,6 +81,9 @@ function generateBlockPaletteReport(array $states) : BlockPaletteReport{
$name = $stateData->getName(); $name = $stateData->getName();
$result->seenTypes[$name] = $name; $result->seenTypes[$name] = $name;
foreach(Utils::stringifyKeys($stateData->getStates()) as $k => $v){ foreach(Utils::stringifyKeys($stateData->getStates()) as $k => $v){
if(!$v instanceof ByteTag && !$v instanceof IntTag && !$v instanceof StringTag){
throw new AssumptionFailedError("Assumed all state tags should be TAG_Byte, TAG_Int or TAG_String, but found $k ($v) on block $name");
}
$result->seenStateValues[$k][$v->getValue()] = $v->getValue(); $result->seenStateValues[$k][$v->getValue()] = $v->getValue();
asort($result->seenStateValues[$k]); asort($result->seenStateValues[$k]);
} }

View File

@ -133,3 +133,15 @@ Released 31st August 2025.
## Fixes ## Fixes
- Fixed banners placed in prior versions getting their tiles deleted (due to missing `Type` tags). - Fixed banners placed in prior versions getting their tiles deleted (due to missing `Type` tags).
# 5.33.2
Released 16th September 2025.
## General
- PHP 8.4 has now been added to the test matrix.
## Fixes
- Fixed PHP 8.4 deprecation notice in `AsyncGeneratorExecutor`.
- Fixed inventory windows breaking if a window is sent while the player has the chat window open (e.g. quickly pressing E followed by / could trigger this).
- Fixed `BlockBreakEvent` being called twice in creative if cancelled.
- Reduced block lag when towering and other situations where the placed block might intersect with the player's AABB. Block lag may still appear on higher latency clients - this is still being worked on.

View File

@ -52,7 +52,7 @@
"symfony/filesystem": "~6.4.0" "symfony/filesystem": "~6.4.0"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "2.1.17", "phpstan/phpstan": "2.1.25",
"phpstan/phpstan-phpunit": "^2.0.0", "phpstan/phpstan-phpunit": "^2.0.0",
"phpstan/phpstan-strict-rules": "^2.0.0", "phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^10.5.24" "phpunit/phpunit": "^10.5.24"

78
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": "27fee330bdcb6ea2373c57cdfb3bc22f", "content-hash": "008c888b5812dda09a0ec6e425453153",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -818,20 +818,20 @@
}, },
{ {
"name": "ramsey/uuid", "name": "ramsey/uuid",
"version": "4.9.0", "version": "4.9.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/ramsey/uuid.git", "url": "https://github.com/ramsey/uuid.git",
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0" "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0", "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440",
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0", "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13", "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14",
"php": "^8.0", "php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0" "ramsey/collection": "^1.2 || ^2.0"
}, },
@ -890,9 +890,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/ramsey/uuid/issues", "issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.9.0" "source": "https://github.com/ramsey/uuid/tree/4.9.1"
}, },
"time": "2025-06-25T14:20:11+00:00" "time": "2025-09-04T20:59:21+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
@ -1204,16 +1204,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.17", "version": "2.1.25",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" "reference": "4087d28bd252895874e174d65e26b2c202ed893a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4087d28bd252895874e174d65e26b2c202ed893a",
"reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", "reference": "4087d28bd252895874e174d65e26b2c202ed893a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1258,25 +1258,25 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-05-21T20:55:28+00:00" "time": "2025-09-12T14:26:42+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
"version": "2.0.6", "version": "2.0.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git", "url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "6b92469f8a7995e626da3aa487099617b8dfa260" "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/6b92469f8a7995e626da3aa487099617b8dfa260", "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9a9b161baee88a5f5c58d816943cff354ff233dc",
"reference": "6b92469f8a7995e626da3aa487099617b8dfa260", "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0.4" "phpstan/phpstan": "^2.1.18"
}, },
"conflict": { "conflict": {
"phpunit/phpunit": "<7.0" "phpunit/phpunit": "<7.0"
@ -1309,9 +1309,9 @@
"description": "PHPUnit extensions and rules for PHPStan", "description": "PHPUnit extensions and rules for PHPStan",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues", "issues": "https://github.com/phpstan/phpstan-phpunit/issues",
"source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.6" "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.7"
}, },
"time": "2025-03-26T12:47:06+00:00" "time": "2025-07-13T11:31:46+00:00"
}, },
{ {
"name": "phpstan/phpstan-strict-rules", "name": "phpstan/phpstan-strict-rules",
@ -1684,16 +1684,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "10.5.53", "version": "10.5.55",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "32768472ebfb6969e6c7399f1c7b09009723f653" "reference": "4b2d546b336876bd9562f24641b08a25335b06b6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/32768472ebfb6969e6c7399f1c7b09009723f653", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4b2d546b336876bd9562f24641b08a25335b06b6",
"reference": "32768472ebfb6969e6c7399f1c7b09009723f653", "reference": "4b2d546b336876bd9562f24641b08a25335b06b6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1714,7 +1714,7 @@
"phpunit/php-timer": "^6.0.0", "phpunit/php-timer": "^6.0.0",
"sebastian/cli-parser": "^2.0.1", "sebastian/cli-parser": "^2.0.1",
"sebastian/code-unit": "^2.0.0", "sebastian/code-unit": "^2.0.0",
"sebastian/comparator": "^5.0.3", "sebastian/comparator": "^5.0.4",
"sebastian/diff": "^5.1.1", "sebastian/diff": "^5.1.1",
"sebastian/environment": "^6.1.0", "sebastian/environment": "^6.1.0",
"sebastian/exporter": "^5.1.2", "sebastian/exporter": "^5.1.2",
@ -1765,7 +1765,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.53" "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.55"
}, },
"funding": [ "funding": [
{ {
@ -1789,7 +1789,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-08-20T14:40:06+00:00" "time": "2025-09-14T06:19:20+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@ -1961,16 +1961,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "5.0.3", "version": "5.0.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e8e53097718d2b53cfb2aa859b06a41abf58c62e",
"reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2026,15 +2026,27 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues", "issues": "https://github.com/sebastianbergmann/comparator/issues",
"security": "https://github.com/sebastianbergmann/comparator/security/policy", "security": "https://github.com/sebastianbergmann/comparator/security/policy",
"source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.4"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
"type": "tidelift"
} }
], ],
"time": "2024-10-18T14:56:07+00:00" "time": "2025-09-07T05:25:07+00:00"
}, },
{ {
"name": "sebastian/complexity", "name": "sebastian/complexity",

View File

@ -32,7 +32,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.33.2"; public const BASE_VERSION = "5.33.2";
public const IS_DEVELOPMENT_BUILD = true; public const IS_DEVELOPMENT_BUILD = false;
public const BUILD_CHANNEL = "stable"; public const BUILD_CHANNEL = "stable";
/** /**

View File

@ -278,6 +278,10 @@ final class BlockStateUpgrader{
private function applyPropertyFlattened(BlockStateUpgradeSchemaFlattenInfo $flattenInfo, string $oldName, array $states) : array{ private function applyPropertyFlattened(BlockStateUpgradeSchemaFlattenInfo $flattenInfo, string $oldName, array $states) : array{
$flattenedValue = $states[$flattenInfo->flattenedProperty] ?? null; $flattenedValue = $states[$flattenInfo->flattenedProperty] ?? null;
$expectedType = $flattenInfo->flattenedPropertyType; $expectedType = $flattenInfo->flattenedPropertyType;
if($expectedType === null){
//TODO: we can't make this non-nullable in a patch release
throw new AssumptionFailedError("We never give this null");
}
if(!$flattenedValue instanceof $expectedType){ if(!$flattenedValue instanceof $expectedType){
//flattened property is not of the expected type, so this transformation is not applicable //flattened property is not of the expected type, so this transformation is not applicable
return [$oldName, $states]; return [$oldName, $states];

View File

@ -52,8 +52,6 @@ class EndCrystal extends Entity implements Explosive{
protected bool $showBase = false; protected bool $showBase = false;
protected ?Vector3 $beamTarget = null; protected ?Vector3 $beamTarget = null;
private bool $primed = false;
protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(2.0, 2.0); } protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(2.0, 2.0); }
protected function getInitialDragMultiplier() : float{ return 1.0; } protected function getInitialDragMultiplier() : float{ return 1.0; }
@ -90,9 +88,11 @@ class EndCrystal extends Entity implements Explosive{
parent::attack($source); parent::attack($source);
if( if(
$source->getCause() !== EntityDamageEvent::CAUSE_VOID && $source->getCause() !== EntityDamageEvent::CAUSE_VOID &&
!$this->isFlaggedForDespawn() &&
!$source->isCancelled() !$source->isCancelled()
){ ){
$this->primed = true; $this->flagForDespawn();
$this->explode();
} }
} }
@ -125,13 +125,6 @@ class EndCrystal extends Entity implements Explosive{
return $nbt; return $nbt;
} }
protected function onDeathUpdate(int $tickDiff) : bool{
if($this->primed){
$this->explode();
}
return true;
}
public function explode() : void{ public function explode() : void{
$ev = new EntityPreExplodeEvent($this, 6); $ev = new EntityPreExplodeEvent($this, 6);
$ev->call(); $ev->call();

View File

@ -64,6 +64,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes;
use pocketmine\network\PacketHandlingException; use pocketmine\network\PacketHandlingException;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Binary;
use pocketmine\utils\ObjectSet; use pocketmine\utils\ObjectSet;
use function array_fill_keys; use function array_fill_keys;
use function array_keys; use function array_keys;
@ -419,6 +420,15 @@ class InventoryManager{
} }
public function onClientRemoveWindow(int $id) : void{ public function onClientRemoveWindow(int $id) : void{
if(Binary::signByte($id) === ContainerIds::NONE){ //TODO: REMOVE signByte() once BedrockProtocol + ext-encoding are implemented
//TODO: HACK! Since 1.21.100 (and probably earlier), the client will send -1 to close windows that it can't
//view for some reason, e.g. if the chat window was already open. This is pretty awkward, since it means
//that we can only assume it refers to the most recently sent window, and if we don't handle it,
//InventoryManager will never get the green light to send subsequent windows, which breaks inventory UIs.
//Fortunately, we already wait for close acks anyway, so the window ID is technically useless...?
$this->session->getLogger()->debug("Client rejected opening of a window, assuming it was $this->lastInventoryNetworkId");
$id = $this->lastInventoryNetworkId;
}
if($id === $this->lastInventoryNetworkId){ if($id === $this->lastInventoryNetworkId){
if(isset($this->networkIdToInventoryMap[$id]) && $id !== $this->pendingCloseWindowId){ if(isset($this->networkIdToInventoryMap[$id]) && $id !== $this->pendingCloseWindowId){
$this->remove($id); $this->remove($id);

View File

@ -89,6 +89,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction;
use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\PredictedResult;
use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData;
use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest; use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest;
use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse; use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse;
@ -498,11 +499,13 @@ class InGamePacketHandler extends PacketHandler{
$blockPos = $data->getBlockPosition(); $blockPos = $data->getBlockPosition();
$vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ()); $vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ());
$this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos); $this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos);
//always sync this in case plugins caused a different result than the client expected if($data->getClientInteractPrediction() === PredictedResult::SUCCESS){
//we *could* try to enhance detection of plugin-altered behaviour, but this would require propagating //always sync this in case plugins caused a different result than the client expected
//more information up the stack. For now I think this is good enough. //we *could* try to enhance detection of plugin-altered behaviour, but this would require propagating
//if only the client would tell us what blocks it thinks changed... //more information up the stack. For now I think this is good enough.
$this->syncBlocksNearby($vBlockPos, $data->getFace()); //if only the client would tell us what blocks it thinks changed...
$this->syncBlocksNearby($vBlockPos, $data->getFace());
}
return true; return true;
case UseItemTransactionData::ACTION_CLICK_AIR: case UseItemTransactionData::ACTION_CLICK_AIR:
if($this->player->isUsingItem()){ if($this->player->isUsingItem()){
@ -717,7 +720,8 @@ class InGamePacketHandler extends PacketHandler{
case PlayerAction::INTERACT_BLOCK: //TODO: ignored (for now) case PlayerAction::INTERACT_BLOCK: //TODO: ignored (for now)
break; break;
case PlayerAction::CREATIVE_PLAYER_DESTROY_BLOCK: case PlayerAction::CREATIVE_PLAYER_DESTROY_BLOCK:
//TODO: do we need to handle this? //in server auth block breaking, we get PREDICT_DESTROY_BLOCK anyway, so this action is redundant
break;
case PlayerAction::PREDICT_DESTROY_BLOCK: case PlayerAction::PREDICT_DESTROY_BLOCK:
self::validateFacing($face); self::validateFacing($face);
if(!$this->player->breakBlock($pos)){ if(!$this->player->breakBlock($pos)){

View File

@ -948,6 +948,12 @@ parameters:
count: 1 count: 1
path: ../../../src/plugin/PluginDescription.php path: ../../../src/plugin/PluginDescription.php
-
message: '#^Property pocketmine\\plugin\\PluginDescription\:\:\$srcNamespacePrefix \(string\) does not accept mixed\.$#'
identifier: assign.propertyType
count: 1
path: ../../../src/plugin/PluginDescription.php
- -
message: '#^Cannot call method addChild\(\) on pocketmine\\permission\\Permission\|null\.$#' message: '#^Cannot call method addChild\(\) on pocketmine\\permission\\Permission\|null\.$#'
identifier: method.nonObject identifier: method.nonObject
@ -990,6 +996,12 @@ parameters:
count: 1 count: 1
path: ../../../src/scheduler/TaskScheduler.php path: ../../../src/scheduler/TaskScheduler.php
-
message: '#^Possibly invalid array key type mixed\.$#'
identifier: offsetAccess.invalidOffset
count: 1
path: ../../../src/thread/ThreadManager.php
- -
message: '#^Cannot access offset string on mixed\.$#' message: '#^Cannot access offset string on mixed\.$#'
identifier: offsetAccess.nonOffsetAccessible identifier: offsetAccess.nonOffsetAccessible

View File

@ -192,18 +192,6 @@ parameters:
count: 1 count: 1
path: ../../../src/network/mcpe/cache/CraftingDataCache.php path: ../../../src/network/mcpe/cache/CraftingDataCache.php
-
message: '#^Method pocketmine\\network\\mcpe\\compression\\ZlibCompressor\:\:getNetworkId\(\) never returns 1 so it can be removed from the return type\.$#'
identifier: return.unusedType
count: 1
path: ../../../src/network/mcpe/compression/ZlibCompressor.php
-
message: '#^Method pocketmine\\network\\mcpe\\compression\\ZlibCompressor\:\:getNetworkId\(\) never returns 255 so it can be removed from the return type\.$#'
identifier: return.unusedType
count: 1
path: ../../../src/network/mcpe/compression/ZlibCompressor.php
- -
message: '#^Parameter \#1 \$states of class pocketmine\\network\\mcpe\\convert\\BlockStateDictionary constructor expects list\<pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\>, array\<int\<0, max\>, pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\> given\.$#' message: '#^Parameter \#1 \$states of class pocketmine\\network\\mcpe\\convert\\BlockStateDictionary constructor expects list\<pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\>, array\<int\<0, max\>, pocketmine\\network\\mcpe\\convert\\BlockStateDictionaryEntry\> given\.$#'
identifier: argument.type identifier: argument.type

View File

@ -30,3 +30,26 @@ parameters:
count: 4 count: 4
path: ../../../src/world/generator/noise/Noise.php path: ../../../src/world/generator/noise/Noise.php
-
message: '#^Parameter \$q00 of static method pocketmine\\world\\generator\\noise\\Noise\:\:bilinearLerp\(\) expects float, float\|null given\.$#'
identifier: argument.type
count: 1
path: ../../../src/world/generator/noise/Noise.php
-
message: '#^Parameter \$q01 of static method pocketmine\\world\\generator\\noise\\Noise\:\:bilinearLerp\(\) expects float, float\|null given\.$#'
identifier: argument.type
count: 1
path: ../../../src/world/generator/noise/Noise.php
-
message: '#^Parameter \$q10 of static method pocketmine\\world\\generator\\noise\\Noise\:\:bilinearLerp\(\) expects float, float\|null given\.$#'
identifier: argument.type
count: 1
path: ../../../src/world/generator/noise/Noise.php
-
message: '#^Parameter \$q11 of static method pocketmine\\world\\generator\\noise\\Noise\:\:bilinearLerp\(\) expects float, float\|null given\.$#'
identifier: argument.type
count: 1
path: ../../../src/world/generator/noise/Noise.php

View File

@ -47,7 +47,7 @@ final class CloningRegistryTraitTest extends TestCase{
public function testGetAllClone() : void{ public function testGetAllClone() : void{
$list1 = TestCloningRegistry::getAll(); $list1 = TestCloningRegistry::getAll();
$list2 = TestCloningRegistry::getAll(); $list2 = TestCloningRegistry::getAll();
foreach(Utils::promoteKeys($list1) as $k => $member){ foreach(Utils::stringifyKeys($list1) as $k => $member){
self::assertNotSame($member, $list2[$k], "VanillaBlocks ought to clone its members"); self::assertNotSame($member, $list2[$k], "VanillaBlocks ought to clone its members");
} }
} }

View File

@ -354,6 +354,9 @@ function processStateGroup(string $oldName, array $upgradeTable, BlockStateUpgra
* @param string[] $strings * @param string[] $strings
*/ */
function findCommonPrefix(array $strings) : string{ function findCommonPrefix(array $strings) : string{
if(count($strings) === 0){
return "";
}
sort($strings, SORT_STRING); sort($strings, SORT_STRING);
$first = $strings[array_key_first($strings)]; $first = $strings[array_key_first($strings)];