From 3f7e7352fb8ef2ce330918608663d8e4d7f928cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 11:57:37 +0000 Subject: [PATCH 01/59] added SplFixedArray generics for phpstan 0.12.9 --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/inventory/BaseInventory.php | 5 ++++- src/pocketmine/item/ItemFactory.php | 5 ++++- src/pocketmine/item/enchantment/Enchantment.php | 5 ++++- src/pocketmine/item/enchantment/EnchantmentList.php | 5 ++++- src/pocketmine/level/Level.php | 8 +++++++- src/pocketmine/level/biome/Biome.php | 5 ++++- src/pocketmine/level/format/Chunk.php | 11 +++++++++-- .../level/generator/biome/BiomeSelector.php | 5 ++++- src/pocketmine/level/generator/noise/Noise.php | 8 ++++++++ 10 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index ac89d3d9f..68f42ea11 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -391,6 +391,7 @@ class BlockFactory{ /** * @internal + * @phpstan-return \SplFixedArray */ public static function getBlockStatesArray() : \SplFixedArray{ return self::$fullList; diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index f33a58430..71d6f258c 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -46,7 +46,10 @@ abstract class BaseInventory implements Inventory{ protected $name; /** @var string */ protected $title; - /** @var \SplFixedArray|(Item|null)[] */ + /** + * @var \SplFixedArray|(Item|null)[] + * @phpstan-var \SplFixedArray + */ protected $slots; /** @var Player[] */ protected $viewers = []; diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 7a22570ab..ed9e969d4 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -43,7 +43,10 @@ use function trim; */ class ItemFactory{ - /** @var \SplFixedArray */ + /** + * @var \SplFixedArray + * @phpstan-var \SplFixedArray + */ private static $list = null; /** diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 56ce04d2d..4ba5e5d32 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -94,7 +94,10 @@ class Enchantment{ public const SLOT_ELYTRA = 0x4000; public const SLOT_TRIDENT = 0x8000; - /** @var \SplFixedArray|Enchantment[] */ + /** + * @var \SplFixedArray|Enchantment[] + * @phpstan-var \SplFixedArray + */ protected static $enchantments; public static function init() : void{ diff --git a/src/pocketmine/item/enchantment/EnchantmentList.php b/src/pocketmine/item/enchantment/EnchantmentList.php index 617ca13af..103d3c1a6 100644 --- a/src/pocketmine/item/enchantment/EnchantmentList.php +++ b/src/pocketmine/item/enchantment/EnchantmentList.php @@ -25,7 +25,10 @@ namespace pocketmine\item\enchantment; class EnchantmentList{ - /** @var \SplFixedArray|EnchantmentEntry[] */ + /** + * @var \SplFixedArray|EnchantmentEntry[] + * @phpstan-var \SplFixedArray + */ private $enchantments; public function __construct(int $size){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 31552943c..87d65c776 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -247,7 +247,10 @@ class Level implements ChunkManager, Metadatable{ /** @var Vector3 */ private $temporalVector; - /** @var \SplFixedArray */ + /** + * @var \SplFixedArray + * @phpstan-var \SplFixedArray + */ private $blockStates; /** @var int */ @@ -1038,6 +1041,9 @@ class Level implements ChunkManager, Metadatable{ unset($this->chunkCache[Level::chunkHash($chunkX, $chunkZ)]); } + /** + * @phpstan-return \SplFixedArray + */ public function getRandomTickedBlocks() : \SplFixedArray{ return $this->randomTickBlocks; } diff --git a/src/pocketmine/level/biome/Biome.php b/src/pocketmine/level/biome/Biome.php index c70acf460..9a92c5548 100644 --- a/src/pocketmine/level/biome/Biome.php +++ b/src/pocketmine/level/biome/Biome.php @@ -49,7 +49,10 @@ abstract class Biome{ public const MAX_BIOMES = 256; - /** @var Biome[]|\SplFixedArray */ + /** + * @var Biome[]|\SplFixedArray + * @phpstan-var \SplFixedArray + */ private static $biomes; /** @var int */ diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 39ce3d2b9..430dee8db 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -72,7 +72,10 @@ class Chunk{ /** @var int */ protected $height = Chunk::MAX_SUBCHUNKS; - /** @var \SplFixedArray|SubChunkInterface[] */ + /** + * @var \SplFixedArray|SubChunkInterface[] + * @phpstan-var \SplFixedArray + */ protected $subChunks; /** @var EmptySubChunk */ @@ -86,7 +89,10 @@ class Chunk{ /** @var Entity[] */ protected $entities = []; - /** @var \SplFixedArray|int[] */ + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ protected $heightMap; /** @var string */ @@ -784,6 +790,7 @@ class Chunk{ /** * @return \SplFixedArray|SubChunkInterface[] + * @phpstan-return \SplFixedArray */ public function getSubChunks() : \SplFixedArray{ return $this->subChunks; diff --git a/src/pocketmine/level/generator/biome/BiomeSelector.php b/src/pocketmine/level/generator/biome/BiomeSelector.php index 0d275acb7..4688e9e88 100644 --- a/src/pocketmine/level/generator/biome/BiomeSelector.php +++ b/src/pocketmine/level/generator/biome/BiomeSelector.php @@ -34,7 +34,10 @@ abstract class BiomeSelector{ /** @var Simplex */ private $rainfall; - /** @var Biome[]|\SplFixedArray */ + /** + * @var Biome[]|\SplFixedArray + * @phpstan-var \SplFixedArray + */ private $map = null; public function __construct(Random $random){ diff --git a/src/pocketmine/level/generator/noise/Noise.php b/src/pocketmine/level/generator/noise/Noise.php index 46203982b..727dd8299 100644 --- a/src/pocketmine/level/generator/noise/Noise.php +++ b/src/pocketmine/level/generator/noise/Noise.php @@ -247,6 +247,10 @@ abstract class Noise{ return $result; } + /** + * @return \SplFixedArray|float[] + * @phpstan-return \SplFixedArray + */ public function getFastNoise1D(int $xSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ if($samplingRate === 0){ throw new \InvalidArgumentException("samplingRate cannot be 0"); @@ -271,6 +275,10 @@ abstract class Noise{ return $noiseArray; } + /** + * @return \SplFixedArray|float[][] + * @phpstan-return \SplFixedArray<\SplFixedArray> + */ public function getFastNoise2D(int $xSize, int $zSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ assert($samplingRate !== 0, new \InvalidArgumentException("samplingRate cannot be 0")); From c43e21235d96c5a15b38a47a7d454702a10511a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 12:57:27 +0000 Subject: [PATCH 02/59] HelpCommand: do not overwrite non-foreach vars in foreach --- src/pocketmine/command/defaults/HelpCommand.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/command/defaults/HelpCommand.php b/src/pocketmine/command/defaults/HelpCommand.php index def7c3246..c4bf73f44 100644 --- a/src/pocketmine/command/defaults/HelpCommand.php +++ b/src/pocketmine/command/defaults/HelpCommand.php @@ -57,22 +57,22 @@ class HelpCommand extends VanillaCommand{ } if(count($args) === 0){ - $command = ""; + $commandName = ""; $pageNumber = 1; }elseif(is_numeric($args[count($args) - 1])){ $pageNumber = (int) array_pop($args); if($pageNumber <= 0){ $pageNumber = 1; } - $command = implode(" ", $args); + $commandName = implode(" ", $args); }else{ - $command = implode(" ", $args); + $commandName = implode(" ", $args); $pageNumber = 1; } $pageHeight = $sender->getScreenLineHeight(); - if($command === ""){ + if($commandName === ""){ /** @var Command[][] $commands */ $commands = []; foreach($sender->getServer()->getCommandMap()->getCommands() as $command){ @@ -95,7 +95,7 @@ class HelpCommand extends VanillaCommand{ return true; }else{ - if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($command))) instanceof Command){ + if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($commandName))) instanceof Command){ if($cmd->testPermissionSilent($sender)){ $message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n"; $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $cmd->getDescription() . "\n"; @@ -105,7 +105,7 @@ class HelpCommand extends VanillaCommand{ return true; } } - $sender->sendMessage(TextFormat::RED . "No help for " . strtolower($command)); + $sender->sendMessage(TextFormat::RED . "No help for " . strtolower($commandName)); return true; } From 88afedd1e8812960445fdceb2e6eefbcf05cd3a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 12:59:59 +0000 Subject: [PATCH 03/59] Human: avoid overwriting non-foreach vars in foreach --- src/pocketmine/entity/Human.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 68fbce2e9..130dfec8d 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -489,9 +489,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $equipment[$mainHandIndex] = $item; } //TODO: check offhand - foreach($this->armorInventory->getContents() as $k => $item){ - if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING)){ - $equipment[$k] = $item; + foreach($this->armorInventory->getContents() as $k => $armorItem){ + if($armorItem instanceof Durable and $armorItem->hasEnchantment(Enchantment::MENDING)){ + $equipment[$k] = $armorItem; } } From 99038c752c7a8d4fd14bb3adcbdb6cc79acbe428 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 13:16:09 +0000 Subject: [PATCH 04/59] Avoid usage of for-loop vars outside of for-loop context these problems were reported by PHPStan strict rules. They aren't actually bugs, but they could become bugs in the future. --- src/pocketmine/level/format/Chunk.php | 12 ++++++------ .../level/generator/populator/GroundCover.php | 3 ++- .../level/generator/populator/TallGrass.php | 4 ++-- src/pocketmine/level/generator/populator/Tree.php | 4 ++-- .../network/mcpe/PlayerNetworkSessionAdapter.php | 3 ++- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 430dee8db..41de5a65a 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -411,8 +411,8 @@ class Chunk{ * @return int New calculated heightmap value (0-256 inclusive) */ public function recalculateHeightMapColumn(int $x, int $z) : int{ - $max = $this->getHighestBlockAt($x, $z); - for($y = $max; $y >= 0; --$y){ + $y = $this->getHighestBlockAt($x, $z); + for(; $y >= 0; --$y){ if(BlockFactory::$lightFilter[$id = $this->getBlockId($x, $y, $z)] > 1 or BlockFactory::$diffusesSkyLight[$id]){ break; } @@ -438,9 +438,9 @@ class Chunk{ for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ + $y = $maxY; $heightMap = $this->getHeightMap($x, $z); - - for($y = $maxY; $y >= $heightMap; --$y){ + for(; $y >= $heightMap; --$y){ $this->setBlockSkyLight($x, $y, $z, 15); } @@ -805,10 +805,10 @@ class Chunk{ //No need to thoroughly prune empties at runtime, this will just reduce performance. continue; } - break; + return $y; } - return $y; + return -1; } /** diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 5961a5487..08cd1c5d2 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -47,7 +47,8 @@ class GroundCover extends Populator{ } $column = $chunk->getBlockIdColumn($x, $z); - for($y = 127; $y > 0; --$y){ + $y = 127; + for(; $y > 0; --$y){ if($column[$y] !== "\x00" and !BlockFactory::get(ord($column[$y]))->isTransparent()){ break; } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 020fb9a11..73f8e1f63 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -77,10 +77,10 @@ class TallGrass extends Populator{ for($y = 127; $y >= 0; --$y){ $b = $this->level->getBlockIdAt($x, $y, $z); if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2 and $b !== Block::SNOW_LAYER){ - break; + return $y + 1; } } - return $y === 0 ? -1 : ++$y; + return -1; } } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index c5a44fad7..16f73578d 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -83,12 +83,12 @@ class Tree extends Populator{ for($y = 127; $y > 0; --$y){ $b = $this->level->getBlockIdAt($x, $y, $z); if($b === Block::DIRT or $b === Block::GRASS){ - break; + return $y + 1; }elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){ return -1; } } - return ++$y; + return -1; } } diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index ca92a9f4f..ab5e8df2e 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -287,7 +287,8 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ if($quoteType === null){ $quoteType = $raw[$i]; }elseif($raw[$i] === $quoteType){ - for($backslashes = 0; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){} + $backslashes = 0; + for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){} if(($backslashes % 2) === 0){ //unescaped quote $quoteType = null; } From 59cf8e95f090d42407671defcd69752a5cc96d57 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 13:17:09 +0000 Subject: [PATCH 05/59] Tree: fixed populator not growing trees any lower than y=2 this would only be a problem for custom generators, but nonetheless... --- src/pocketmine/level/generator/populator/Tree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index 16f73578d..997107cf3 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -80,7 +80,7 @@ class Tree extends Populator{ } private function getHighestWorkableBlock(int $x, int $z) : int{ - for($y = 127; $y > 0; --$y){ + for($y = 127; $y >= 0; --$y){ $b = $this->level->getBlockIdAt($x, $y, $z); if($b === Block::DIRT or $b === Block::GRASS){ return $y + 1; From 896cca07780edb126473b185c4c951930149c38d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 13:36:45 +0000 Subject: [PATCH 06/59] store composer cache for travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 03b953883..56c3327d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,5 +25,8 @@ script: - composer install --no-dev - ./tests/travis.sh -t4 +cache: + directories: + - $HOME/.composer/cache/files notifications: email: false From b96bb7d8242b1ca50438127e1039cf81954c31cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 13:55:38 +0000 Subject: [PATCH 07/59] Player: use strict base64_decode() for login decoding though, perhaps we should beware of false returns? --- src/pocketmine/Player.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 21ab25bee..98a6109a3 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1860,12 +1860,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $skinData = new SkinData( $packet->clientData["SkinId"], - base64_decode($packet->clientData["SkinResourcePatch"] ?? ""), - new SkinImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData"])), + base64_decode($packet->clientData["SkinResourcePatch"] ?? "", true), + new SkinImage($packet->clientData["SkinImageHeight"], $packet->clientData["SkinImageWidth"], base64_decode($packet->clientData["SkinData"], true)), $animations, - new SkinImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "")), - base64_decode($packet->clientData["SkinGeometryData"] ?? ""), - base64_decode($packet->clientData["SkinAnimationData"] ?? ""), + new SkinImage($packet->clientData["CapeImageHeight"], $packet->clientData["CapeImageWidth"], base64_decode($packet->clientData["CapeData"] ?? "", true)), + base64_decode($packet->clientData["SkinGeometryData"] ?? "", true), + base64_decode($packet->clientData["SkinAnimationData"] ?? "", true), $packet->clientData["PremiumSkin"] ?? false, $packet->clientData["PersonaSkin"] ?? false, $packet->clientData["CapeOnClassicSkin"] ?? false, From e5a2cfb65fb2a5e7d4b187755fe2b75fe382c4d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 15:44:06 +0000 Subject: [PATCH 08/59] avoid type juggling in conditions, always use explicit boolean conditions --- src/pocketmine/Server.php | 8 ++++---- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Block.php | 2 +- src/pocketmine/block/DoublePlant.php | 4 ++-- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Vine.php | 2 +- src/pocketmine/entity/DataPropertyManager.php | 4 ++-- src/pocketmine/entity/Entity.php | 6 +++--- src/pocketmine/inventory/CraftingManager.php | 2 +- src/pocketmine/level/SimpleChunkManager.php | 16 ++++++++-------- .../network/mcpe/NetworkBinaryStream.php | 2 +- .../mcpe/protocol/AdventureSettingsPacket.php | 4 ++-- .../network/mcpe/protocol/AnimatePacket.php | 4 ++-- .../mcpe/protocol/AvailableCommandsPacket.php | 10 +++++----- .../mcpe/protocol/MoveActorDeltaPacket.php | 8 ++++---- src/pocketmine/updater/AutoUpdater.php | 6 +++--- src/pocketmine/utils/Utils.php | 4 ++-- 17 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 9688b085a..110c2eae2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1885,7 +1885,7 @@ class Server{ $this->rcon->stop(); } - if($this->getProperty("network.upnp-forwarding", false)){ + if((bool) $this->getProperty("network.upnp-forwarding", false)){ $this->logger->info("[UPnP] Removing port forward..."); UPnP::RemovePortForward($this->getPort()); } @@ -1958,12 +1958,12 @@ class Server{ $this->network->blockAddress($entry->getName(), -1); } - if($this->getProperty("settings.send-usage", true)){ + if((bool) $this->getProperty("settings.send-usage", true)){ $this->sendUsageTicker = 6000; $this->sendUsage(SendUsageTask::TYPE_OPEN); } - if($this->getProperty("network.upnp-forwarding", false)){ + if((bool) $this->getProperty("network.upnp-forwarding", false)){ $this->logger->info("[UPnP] Trying to port forward..."); try{ UPnP::PortForward($this->getPort()); @@ -2089,7 +2089,7 @@ class Server{ } if($report){ - $url = ($this->getProperty("auto-report.use-https", true) ? "https" : "http") . "://" . $this->getProperty("auto-report.host", "crash.pmmp.io") . "/submit/api"; + $url = ((bool) $this->getProperty("auto-report.use-https", true) ? "https" : "http") . "://" . $this->getProperty("auto-report.host", "crash.pmmp.io") . "/submit/api"; $reply = Internet::postURL($url, [ "report" => "yes", "name" => $this->getName() . " " . $this->getPocketMineVersion(), diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 73aceebb5..2eb8880af 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -78,7 +78,7 @@ class Anvil extends Fallable{ public function recalculateBoundingBox() : ?AxisAlignedBB{ $inset = 0.125; - if($this->meta & 0x01){ //east/west + if(($this->meta & 0x01) !== 0){ //east/west return new AxisAlignedBB( $this->x, $this->y, diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index f9e4d8cc4..df18785e1 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -563,7 +563,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return AxisAlignedBB[] */ protected function recalculateCollisionBoxes() : array{ - if($bb = $this->recalculateBoundingBox()){ + if(($bb = $this->recalculateBoundingBox()) !== null){ return [$bb]; } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 7ed21c5f9..ccb8c1cbd 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -70,7 +70,7 @@ class DoublePlant extends Flowable{ * Returns whether this double-plant has a corresponding other half. */ public function isValidHalfPlant() : bool{ - if($this->meta & self::BITFLAG_TOP){ + if(($this->meta & self::BITFLAG_TOP) !== 0){ $other = $this->getSide(Vector3::SIDE_DOWN); }else{ $other = $this->getSide(Vector3::SIDE_UP); @@ -102,7 +102,7 @@ class DoublePlant extends Flowable{ } public function getDrops(Item $item) : array{ - if($this->meta & self::BITFLAG_TOP){ + if(($this->meta & self::BITFLAG_TOP) !== 0){ if($this->isCompatibleWithTool($item)){ return parent::getDrops($item); } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index a760e604e..788e4a781 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -172,7 +172,7 @@ class Leaves extends Transparent{ } public function getDrops(Item $item) : array{ - if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ + if(($item->getBlockToolType() & BlockToolType::TYPE_SHEARS) !== 0){ return $this->getDropsForCompatibleTool($item); } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index c451d0bae..dadc7a329 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -197,7 +197,7 @@ class Vine extends Flowable{ } public function getDrops(Item $item) : array{ - if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ + if(($item->getBlockToolType() & BlockToolType::TYPE_SHEARS) !== 0){ return $this->getDropsForCompatibleTool($item); } diff --git a/src/pocketmine/entity/DataPropertyManager.php b/src/pocketmine/entity/DataPropertyManager.php index 78cdcfafa..d3f3afcb1 100644 --- a/src/pocketmine/entity/DataPropertyManager.php +++ b/src/pocketmine/entity/DataPropertyManager.php @@ -115,7 +115,7 @@ class DataPropertyManager{ } public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value ? $value->floor() : null, $force); + $this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value !== null ? $value->floor() : null, $force); } public function getLong(int $key) : ?int{ @@ -135,7 +135,7 @@ class DataPropertyManager{ } public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value ? $value->asVector3() : null, $force); + $this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value !== null ? $value->asVector3() : null, $force); } public function removeProperty(int $key) : void{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index acda13eb7..0c511a9ad 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -424,9 +424,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ new DoubleTag("", $pos->z) ]), new ListTag("Motion", [ - new DoubleTag("", $motion ? $motion->x : 0.0), - new DoubleTag("", $motion ? $motion->y : 0.0), - new DoubleTag("", $motion ? $motion->z : 0.0) + new DoubleTag("", $motion !== null ? $motion->x : 0.0), + new DoubleTag("", $motion !== null ? $motion->y : 0.0), + new DoubleTag("", $motion !== null ? $motion->z : 0.0) ]), new ListTag("Rotation", [ new FloatTag("", $yaw), diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index add9969e2..661811fb7 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -144,7 +144,7 @@ class CraftingManager{ */ public static function sort(Item $i1, Item $i2){ //Use spaceship operator to compare each property, then try the next one if they are equivalent. - ($retval = $i1->getId() <=> $i2->getId()) === 0 && ($retval = $i1->getDamage() <=> $i2->getDamage()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()); + ($retval = $i1->getId() <=> $i2->getId()) === 0 && ($retval = $i1->getDamage() <=> $i2->getDamage()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()) === 0; return $retval; } diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index da236cc50..3f8b46ea3 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -51,7 +51,7 @@ class SimpleChunkManager implements ChunkManager{ * @return int 0-255 */ public function getBlockIdAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBlockId($x & 0xf, $y, $z & 0xf); } return 0; @@ -65,7 +65,7 @@ class SimpleChunkManager implements ChunkManager{ * @return void */ public function setBlockIdAt(int $x, int $y, int $z, int $id){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ $chunk->setBlockId($x & 0xf, $y, $z & 0xf, $id); } } @@ -76,7 +76,7 @@ class SimpleChunkManager implements ChunkManager{ * @return int 0-15 */ public function getBlockDataAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBlockData($x & 0xf, $y, $z & 0xf); } return 0; @@ -90,13 +90,13 @@ class SimpleChunkManager implements ChunkManager{ * @return void */ public function setBlockDataAt(int $x, int $y, int $z, int $data){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ $chunk->setBlockData($x & 0xf, $y, $z & 0xf, $data); } } public function getBlockLightAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBlockLight($x & 0xf, $y, $z & 0xf); } @@ -104,13 +104,13 @@ class SimpleChunkManager implements ChunkManager{ } public function setBlockLightAt(int $x, int $y, int $z, int $level){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ $chunk->setBlockLight($x & 0xf, $y, $z & 0xf, $level); } } public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBlockSkyLight($x & 0xf, $y, $z & 0xf); } @@ -118,7 +118,7 @@ class SimpleChunkManager implements ChunkManager{ } public function setBlockSkyLightAt(int $x, int $y, int $z, int $level){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ $chunk->setBlockSkyLight($x & 0xf, $y, $z & 0xf, $level); } } diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 6bf5d4dac..f197ac3b7 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -516,7 +516,7 @@ class NetworkBinaryStream extends BinaryStream{ * @see NetworkBinaryStream::putVector3() */ public function putVector3Nullable(?Vector3 $vector) : void{ - if($vector){ + if($vector !== null){ $this->putVector3($vector); }else{ $this->putLFloat(0.0); diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php index 6712ab2d7..b6c72b01e 100644 --- a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php @@ -94,7 +94,7 @@ class AdventureSettingsPacket extends DataPacket{ } public function getFlag(int $flag) : bool{ - if($flag & self::BITFLAG_SECOND_SET){ + if(($flag & self::BITFLAG_SECOND_SET) !== 0){ return ($this->flags2 & $flag) !== 0; } @@ -105,7 +105,7 @@ class AdventureSettingsPacket extends DataPacket{ * @return void */ public function setFlag(int $flag, bool $value){ - if($flag & self::BITFLAG_SECOND_SET){ + if(($flag & self::BITFLAG_SECOND_SET) !== 0){ $flagSet =& $this->flags2; }else{ $flagSet =& $this->flags; diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 6b9a8e1a2..75f67a471 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -47,7 +47,7 @@ class AnimatePacket extends DataPacket{ protected function decodePayload(){ $this->action = $this->getVarInt(); $this->entityRuntimeId = $this->getEntityRuntimeId(); - if($this->action & 0x80){ + if(($this->action & 0x80) !== 0){ $this->float = $this->getLFloat(); } } @@ -55,7 +55,7 @@ class AnimatePacket extends DataPacket{ protected function encodePayload(){ $this->putVarInt($this->action); $this->putEntityRuntimeId($this->entityRuntimeId); - if($this->action & 0x80){ + if(($this->action & 0x80) !== 0){ $this->putLFloat($this->float); } } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index d2c7104c2..883e3724f 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -295,13 +295,13 @@ class AvailableCommandsPacket extends DataPacket{ $parameter->isOptional = $this->getBool(); $parameter->flags = $this->getByte(); - if($parameter->paramType & self::ARG_FLAG_ENUM){ + if(($parameter->paramType & self::ARG_FLAG_ENUM) !== 0){ $index = ($parameter->paramType & 0xffff); $parameter->enum = $enums[$index] ?? null; if($parameter->enum === null){ throw new \UnexpectedValueException("deserializing $retval->commandName parameter $parameter->paramName: expected enum at $index, but got none"); } - }elseif($parameter->paramType & self::ARG_FLAG_POSTFIX){ + }elseif(($parameter->paramType & self::ARG_FLAG_POSTFIX) !== 0){ $index = ($parameter->paramType & 0xffff); $parameter->postfix = $postfixes[$index] ?? null; if($parameter->postfix === null){ @@ -365,8 +365,8 @@ class AvailableCommandsPacket extends DataPacket{ * @phpstan-param array $postfixes */ private function argTypeToString(int $argtype, array $postfixes) : string{ - if($argtype & self::ARG_FLAG_VALID){ - if($argtype & self::ARG_FLAG_ENUM){ + if(($argtype & self::ARG_FLAG_VALID) !== 0){ + if(($argtype & self::ARG_FLAG_ENUM) !== 0){ return "stringenum (" . ($argtype & 0xffff) . ")"; } @@ -392,7 +392,7 @@ class AvailableCommandsPacket extends DataPacket{ case self::ARG_TYPE_COMMAND: return "command"; } - }elseif($argtype & self::ARG_FLAG_POSTFIX){ + }elseif(($argtype & self::ARG_FLAG_POSTFIX) !== 0){ $postfix = $postfixes[$argtype & 0xffff]; return "int (postfix $postfix)"; diff --git a/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php index c92265abd..1728b936d 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -55,14 +55,14 @@ class MoveActorDeltaPacket extends DataPacket{ public $zRot = 0.0; private function maybeReadCoord(int $flag) : int{ - if($this->flags & $flag){ + if(($this->flags & $flag) !== 0){ return $this->getVarInt(); } return 0; } private function maybeReadRotation(int $flag) : float{ - if($this->flags & $flag){ + if(($this->flags & $flag) !== 0){ return $this->getByteRotation(); } return 0.0; @@ -80,13 +80,13 @@ class MoveActorDeltaPacket extends DataPacket{ } private function maybeWriteCoord(int $flag, int $val) : void{ - if($this->flags & $flag){ + if(($this->flags & $flag) !== 0){ $this->putVarInt($val); } } private function maybeWriteRotation(int $flag, float $val) : void{ - if($this->flags & $flag){ + if(($this->flags & $flag) !== 0){ $this->putByteRotation($val); } } diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index e27a406da..e0d35adcc 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -53,7 +53,7 @@ class AutoUpdater{ $this->server = $server; $this->endpoint = "http://$endpoint/api/"; - if($server->getProperty("auto-updater.enabled", true)){ + if((bool) $server->getProperty("auto-updater.enabled", true)){ $this->doCheck(); } } @@ -71,10 +71,10 @@ class AutoUpdater{ $this->checkUpdate(); if($this->hasUpdate()){ (new UpdateNotifyEvent($this))->call(); - if($this->server->getProperty("auto-updater.on-update.warn-console", true)){ + if((bool) $this->server->getProperty("auto-updater.on-update.warn-console", true)){ $this->showConsoleUpdate(); } - }elseif($this->server->getProperty("auto-updater.preferred-channel", true)){ + }else{ if(!\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() !== "stable"){ $this->showChannelSuggestionStable(); }elseif(\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() === "stable"){ diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 46e291c0d..f68eab4a3 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -478,7 +478,7 @@ class Utils{ $hash = 0; for($i = 0, $len = strlen($string); $i < $len; $i++){ $ord = ord($string[$i]); - if($ord & 0x80){ + if(($ord & 0x80) !== 0){ $ord -= 0x100; } $hash = 31 * $hash + $ord; @@ -671,7 +671,7 @@ class Utils{ * @throws \ErrorException */ public static function errorExceptionHandler(int $severity, string $message, string $file, int $line) : bool{ - if(error_reporting() & $severity){ + if((error_reporting() & $severity) !== 0){ throw new \ErrorException($message, 0, $severity, $file, $line); } From fd2a7797bd53326a16861450f1e8ec6c1f8905c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 15:55:41 +0000 Subject: [PATCH 09/59] include make-release.php in phpstan analysis --- build/make-release.php | 62 +++++++++++++++++++++++++----------------- phpstan.neon.dist | 2 ++ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index f7be518e7..d78f9adcc 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\build_script; +namespace pocketmine\build\make_release; use pocketmine\utils\VersionString; use function dirname; @@ -37,17 +37,6 @@ use const STDIN; require_once dirname(__DIR__) . '/vendor/autoload.php'; -if(isset($argv[1])){ - $currentVer = new VersionString($argv[1]); -}else{ - $currentVer = new VersionString(BASE_VERSION); -} -$nextVer = new VersionString(sprintf( - "%u.%u.%u", - $currentVer->getMajor(), - $currentVer->getMinor(), - $currentVer->getPatch() + 1 -)); function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{ $versionInfo = file_get_contents($versionInfoPath); @@ -63,17 +52,40 @@ function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev ); file_put_contents($versionInfoPath, $versionInfo); } -$versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php'; -replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false); -echo "please add appropriate notes to the changelog and press enter..."; -fgets(STDIN); -system('git add "' . dirname(__DIR__) . '/changelogs"'); -system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"'); -system('git tag ' . $currentVer->getBaseVersion()); -replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true); -system('git add "' . $versionInfoPath . '"'); -system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"'); -echo "pushing changes in 5 seconds\n"; -sleep(5); -system('git push origin HEAD ' . $currentVer->getBaseVersion()); +/** + * @param string[] $argv + * @phpstan-param list $argv + */ +function main(array $argv) : void{ + if(isset($argv[1])){ + $currentVer = new VersionString($argv[1]); + }else{ + $currentVer = new VersionString(BASE_VERSION); + } + $nextVer = new VersionString(sprintf( + "%u.%u.%u", + $currentVer->getMajor(), + $currentVer->getMinor(), + $currentVer->getPatch() + 1 + )); + + $versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php'; + replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false); + + echo "please add appropriate notes to the changelog and press enter..."; + fgets(STDIN); + system('git add "' . dirname(__DIR__) . '/changelogs"'); + system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"'); + system('git tag ' . $currentVer->getBaseVersion()); + replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true); + system('git add "' . $versionInfoPath . '"'); + system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"'); + echo "pushing changes in 5 seconds\n"; + sleep(5); + system('git push origin HEAD ' . $currentVer->getBaseVersion()); +} + +if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){ + main($argv); +} diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c5db920bf..28b369554 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -11,9 +11,11 @@ parameters: autoload_files: - tests/phpstan/bootstrap.php - src/pocketmine/PocketMine.php + - build/make-release.php - build/server-phar.php paths: - src + - build/make-release.php - build/server-phar.php dynamicConstantNames: - pocketmine\IS_DEVELOPMENT_BUILD From fa82cb26d89bb36d579e10fc73cdb17b9fe13c03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 16:35:10 +0000 Subject: [PATCH 10/59] added native types to closures (phpstan-strict-rules) --- build/server-phar.php | 2 +- src/pocketmine/Server.php | 4 ++-- src/pocketmine/command/CommandReader.php | 2 +- src/pocketmine/command/defaults/BanListCommand.php | 2 +- src/pocketmine/command/defaults/ListCommand.php | 4 ++-- src/pocketmine/command/defaults/TeleportCommand.php | 2 +- src/pocketmine/entity/AttributeMap.php | 2 +- src/pocketmine/lang/BaseLang.php | 2 +- src/pocketmine/level/format/io/region/McRegion.php | 2 +- .../network/mcpe/protocol/AvailableCommandsPacket.php | 2 +- .../network/mcpe/protocol/ClientCacheBlobStatusPacket.php | 4 ++-- .../network/mcpe/protocol/ClientCacheMissResponsePacket.php | 2 +- src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php | 2 +- .../network/mcpe/protocol/types/CommandEnumConstraint.php | 2 +- src/pocketmine/network/rcon/RCON.php | 2 +- src/pocketmine/network/rcon/RCONInstance.php | 2 +- src/pocketmine/tile/Sign.php | 2 +- src/pocketmine/utils/MainLogger.php | 4 ++-- src/pocketmine/utils/ServerKiller.php | 2 +- src/pocketmine/utils/Utils.php | 2 +- 20 files changed, 24 insertions(+), 24 deletions(-) diff --git a/build/server-phar.php b/build/server-phar.php index d3d700be9..d99bf9943 100644 --- a/build/server-phar.php +++ b/build/server-phar.php @@ -62,7 +62,7 @@ function preg_quote_array(array $strings, string $delim = null) : array{ */ function buildPhar(string $pharPath, string $basePath, array $includedPaths, array $metadata, string $stub, int $signatureAlgo = \Phar::SHA1, ?int $compression = null){ $basePath = rtrim(str_replace("/", DIRECTORY_SEPARATOR, $basePath), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $includedPaths = array_map(function($path){ + $includedPaths = array_map(function(string $path) : string{ return rtrim(str_replace("/", DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; }, $includedPaths); yield "Creating output file $pharPath"; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 110c2eae2..3c9a373be 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1051,7 +1051,7 @@ class Server{ } $path = $this->getDataPath() . "worlds/" . $name . "/"; if(!($this->getLevelByName($name) instanceof Level)){ - return is_dir($path) and count(array_filter(scandir($path, SCANDIR_SORT_NONE), function($v){ + return is_dir($path) and count(array_filter(scandir($path, SCANDIR_SORT_NONE), function(string $v) : bool{ return $v !== ".." and $v !== "."; })) > 0; } @@ -1284,7 +1284,7 @@ class Server{ * @return void */ public static function microSleep(int $microseconds){ - Server::$sleeper->synchronized(function(int $ms){ + Server::$sleeper->synchronized(function(int $ms) : void{ Server::$sleeper->wait($ms); }, $microseconds); } diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index d7dae9eeb..656d82464 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -154,7 +154,7 @@ class CommandReader extends Thread{ case self::TYPE_PIPED: if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF $this->initStdin(); - $this->synchronized(function(){ + $this->synchronized(function() : void{ $this->wait(200000); }); //prevent CPU waste if it's end of pipe return true; //loop back round diff --git a/src/pocketmine/command/defaults/BanListCommand.php b/src/pocketmine/command/defaults/BanListCommand.php index ca75f9767..90212f815 100644 --- a/src/pocketmine/command/defaults/BanListCommand.php +++ b/src/pocketmine/command/defaults/BanListCommand.php @@ -63,7 +63,7 @@ class BanListCommand extends VanillaCommand{ } $list = $list->getEntries(); - $message = implode(", ", array_map(function(BanEntry $entry){ + $message = implode(", ", array_map(function(BanEntry $entry) : string{ return $entry->getName(); }, $list)); diff --git a/src/pocketmine/command/defaults/ListCommand.php b/src/pocketmine/command/defaults/ListCommand.php index f87248096..6915ee39a 100644 --- a/src/pocketmine/command/defaults/ListCommand.php +++ b/src/pocketmine/command/defaults/ListCommand.php @@ -47,9 +47,9 @@ class ListCommand extends VanillaCommand{ return true; } - $playerNames = array_map(function(Player $player){ + $playerNames = array_map(function(Player $player) : string{ return $player->getName(); - }, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender){ + }, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender) : bool{ return $player->isOnline() and (!($sender instanceof Player) or $sender->canSee($player)); })); diff --git a/src/pocketmine/command/defaults/TeleportCommand.php b/src/pocketmine/command/defaults/TeleportCommand.php index 353a33f4f..c53bd9240 100644 --- a/src/pocketmine/command/defaults/TeleportCommand.php +++ b/src/pocketmine/command/defaults/TeleportCommand.php @@ -52,7 +52,7 @@ class TeleportCommand extends VanillaCommand{ return true; } - $args = array_values(array_filter($args, function($arg){ + $args = array_values(array_filter($args, function(string $arg) : bool{ return $arg !== ""; })); if(count($args) < 1 or count($args) > 6){ diff --git a/src/pocketmine/entity/AttributeMap.php b/src/pocketmine/entity/AttributeMap.php index 80aee14c7..930e90c14 100644 --- a/src/pocketmine/entity/AttributeMap.php +++ b/src/pocketmine/entity/AttributeMap.php @@ -51,7 +51,7 @@ class AttributeMap implements \ArrayAccess{ * @return Attribute[] */ public function needSend() : array{ - return array_filter($this->attributes, function(Attribute $attribute){ + return array_filter($this->attributes, function(Attribute $attribute) : bool{ return $attribute->isSyncable() and $attribute->isDesynchronized(); }); } diff --git a/src/pocketmine/lang/BaseLang.php b/src/pocketmine/lang/BaseLang.php index 3100bf89e..aa5eb6bb0 100644 --- a/src/pocketmine/lang/BaseLang.php +++ b/src/pocketmine/lang/BaseLang.php @@ -56,7 +56,7 @@ class BaseLang{ $allFiles = scandir($path, SCANDIR_SORT_NONE); if($allFiles !== false){ - $files = array_filter($allFiles, function($filename){ + $files = array_filter($allFiles, function(string $filename) : bool{ return substr($filename, -4) === ".ini"; }); diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index d6a51fd71..3516fc598 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -239,7 +239,7 @@ class McRegion extends BaseLevelProvider{ $isValid = (file_exists($path . "/level.dat") and is_dir($path . "/region/")); if($isValid){ - $files = array_filter(scandir($path . "/region/", SCANDIR_SORT_NONE), function($file){ + $files = array_filter(scandir($path . "/region/", SCANDIR_SORT_NONE), function(string $file) : bool{ return substr($file, strrpos($file, ".") + 1, 2) === "mc"; //region file }); diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 883e3724f..eac4833d0 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -413,7 +413,7 @@ class AvailableCommandsPacket extends DataPacket{ /** @var CommandEnum[] $enums */ $enums = []; - $addEnumFn = static function(CommandEnum $enum) use (&$enums, &$enumIndexes, &$enumValueIndexes){ + $addEnumFn = static function(CommandEnum $enum) use (&$enums, &$enumIndexes, &$enumValueIndexes) : void{ if(!isset($enumIndexes[$enum->enumName])){ $enums[$enumIndexes[$enum->enumName] = count($enumIndexes)] = $enum; } diff --git a/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 263ae927a..7957c94a1 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -42,8 +42,8 @@ class ClientCacheBlobStatusPacket extends DataPacket/* implements ServerboundPac */ public static function create(array $hitHashes, array $missHashes) : self{ //type checks - (static function(int ...$hashes){})(...$hitHashes); - (static function(int ...$hashes){})(...$missHashes); + (static function(int ...$hashes) : void{})(...$hitHashes); + (static function(int ...$hashes) : void{})(...$missHashes); $result = new self; $result->hitHashes = $hitHashes; diff --git a/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php index d22e03b64..28e823cbc 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -40,7 +40,7 @@ class ClientCacheMissResponsePacket extends DataPacket/* implements ClientboundP */ public static function create(array $blobs) : self{ //type check - (static function(ChunkCacheBlob ...$blobs){})(...$blobs); + (static function(ChunkCacheBlob ...$blobs) : void{})(...$blobs); $result = new self; $result->blobs = $blobs; diff --git a/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php b/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php index c801e8852..43c5ee894 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php @@ -60,7 +60,7 @@ class LevelChunkPacket extends DataPacket/* implements ClientboundPacket*/{ * @param int[] $usedBlobHashes */ public static function withCache(int $chunkX, int $chunkZ, int $subChunkCount, array $usedBlobHashes, string $extraPayload) : self{ - (static function(int ...$hashes){})(...$usedBlobHashes); + (static function(int ...$hashes) : void{})(...$usedBlobHashes); $result = new self; $result->chunkX = $chunkX; $result->chunkZ = $chunkZ; diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandEnumConstraint.php b/src/pocketmine/network/mcpe/protocol/types/CommandEnumConstraint.php index 9de6a853e..4b66b0a75 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandEnumConstraint.php +++ b/src/pocketmine/network/mcpe/protocol/types/CommandEnumConstraint.php @@ -35,7 +35,7 @@ class CommandEnumConstraint{ * @param int[] $constraints */ public function __construct(CommandEnum $enum, int $valueOffset, array $constraints){ - (static function(int ...$_){})(...$constraints); + (static function(int ...$_) : void{})(...$constraints); if(!isset($enum->enumValues[$valueOffset])){ throw new \InvalidArgumentException("Invalid enum value offset $valueOffset"); } diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 989503ed7..8da98c165 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -128,7 +128,7 @@ class RCON{ } $this->instance->response = TextFormat::clean($response->getMessage()); - $this->instance->synchronized(function(RCONInstance $thread){ + $this->instance->synchronized(function(RCONInstance $thread) : void{ $thread->notify(); }, $this->instance); } diff --git a/src/pocketmine/network/rcon/RCONInstance.php b/src/pocketmine/network/rcon/RCONInstance.php index d555e6297..73999cb0d 100644 --- a/src/pocketmine/network/rcon/RCONInstance.php +++ b/src/pocketmine/network/rcon/RCONInstance.php @@ -233,7 +233,7 @@ class RCONInstance extends Thread{ } if($payload !== ""){ $this->cmd = ltrim($payload); - $this->synchronized(function(){ + $this->synchronized(function() : void{ $this->notifier->wakeupSleeper(); $this->wait(); }); diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 4fb154177..edfcf3735 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -157,7 +157,7 @@ class Sign extends Spawnable{ $removeFormat = $player->getRemoveFormat(); - $ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat){ return TextFormat::clean($line, $removeFormat); }, $lines)); + $ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat) : string{ return TextFormat::clean($line, $removeFormat); }, $lines)); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index f89d0ce68..9c41de7a5 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -329,7 +329,7 @@ class MainLogger extends \AttachableThreadedLogger{ */ public function syncFlushBuffer(){ $this->syncFlush = true; - $this->synchronized(function(){ + $this->synchronized(function() : void{ $this->notify(); //write immediately while($this->syncFlush){ @@ -364,7 +364,7 @@ class MainLogger extends \AttachableThreadedLogger{ while(!$this->shutdown){ $this->writeLogStream($logResource); - $this->synchronized(function(){ + $this->synchronized(function() : void{ $this->wait(25000); }); } diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index 6f9e84f71..da43895f9 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -48,7 +48,7 @@ class ServerKiller extends Thread{ public function run(){ $this->registerClassLoader(); $start = time(); - $this->synchronized(function(){ + $this->synchronized(function() : void{ if(!$this->stopped){ $this->wait($this->time * 1000000); } diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index f68eab4a3..ad3ff0b0b 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -590,7 +590,7 @@ class Utils{ $args = $trace[$i]["params"]; } - $params = implode(", ", array_map(function($value) use($maxStringLength){ + $params = implode(", ", array_map(function($value) use($maxStringLength) : string{ if(is_object($value)){ return "object " . self::getNiceClassName($value); } From ad87c11ae1157529e159cdcce239b712b420d9be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 16:36:11 +0000 Subject: [PATCH 11/59] ThreadManager: use array-access instead of variable property access --- src/pocketmine/ThreadManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/ThreadManager.php index b84f6509a..4d232c3fa 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/ThreadManager.php @@ -52,7 +52,7 @@ class ThreadManager extends \Volatile{ */ public function add($thread){ if($thread instanceof Thread or $thread instanceof Worker){ - $this->{spl_object_hash($thread)} = $thread; + $this[spl_object_hash($thread)] = $thread; } } @@ -63,7 +63,7 @@ class ThreadManager extends \Volatile{ */ public function remove($thread){ if($thread instanceof Thread or $thread instanceof Worker){ - unset($this->{spl_object_hash($thread)}); + unset($this[spl_object_hash($thread)]); } } From df8e0cf1f5ba0ed7af315db96b7a1172f1dc0def Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 17:06:05 +0000 Subject: [PATCH 12/59] MemoryManager: eliminate unnecessary reference abuse in continueDump() this makes the flow of data easier to understand, and also sidesteps some PHPStan bugs. --- src/pocketmine/MemoryManager.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 1a5c0b8be..63d1db83c 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -337,7 +337,7 @@ class MemoryManager{ } $staticCount++; - self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $staticProperties[$className][$property->getName()] = self::continueDump($property->getValue(), $objects, $refCounts, 0, $maxNesting, $maxStringSize); } if(count($staticProperties[$className]) === 0){ @@ -370,14 +370,14 @@ class MemoryManager{ } $globalCount++; - self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $globalVariables[$varName] = self::continueDump($value, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $logger->info("[Dump] Wrote $globalCount global variables"); } - self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $data = self::continueDump($startingObject, $objects, $refCounts, 0, $maxNesting, $maxStringSize); do{ $continue = false; @@ -425,7 +425,7 @@ class MemoryManager{ $property->setAccessible(true); } - self::continueDump($property->getValue($object), $info["properties"][$name], $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $info["properties"][$name] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); } } @@ -452,14 +452,14 @@ class MemoryManager{ /** * @param mixed $from - * @param mixed $data reference parameter * @param object[] $objects reference parameter * @param int[] $refCounts reference parameter + * + * @return mixed */ - private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : void{ + private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ if($maxNesting <= 0){ - $data = "(error) NESTING LIMIT REACHED"; - return; + return "(error) NESTING LIMIT REACHED"; } --$maxNesting; @@ -475,12 +475,11 @@ class MemoryManager{ $data = "(object) $hash@" . get_class($from); }elseif(is_array($from)){ if($recursion >= 5){ - $data = "(error) ARRAY RECURSION LIMIT REACHED"; - return; + return "(error) ARRAY RECURSION LIMIT REACHED"; } $data = []; foreach($from as $key => $value){ - self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); + $data[$key] = self::continueDump($value, $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize); } }elseif(is_string($from)){ $data = "(string) len(" . strlen($from) . ") " . substr(Utils::printable($from), 0, $maxStringSize); @@ -489,5 +488,7 @@ class MemoryManager{ }else{ $data = $from; } + + return $data; } } From 0f6949ac344b922e9f5879ae50e16577b821cb96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 17:11:08 +0000 Subject: [PATCH 13/59] phpstan 0.12.9 --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 7e67f170b..c059b4290 100644 --- a/composer.lock +++ b/composer.lock @@ -430,16 +430,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.8", + "version": "0.12.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "62a552602b7586d82826231f2fd4cbfe39fe0b1d" + "reference": "297cb2458a96ea96d5e9d6ef38f1b7305c071f32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/62a552602b7586d82826231f2fd4cbfe39fe0b1d", - "reference": "62a552602b7586d82826231f2fd4cbfe39fe0b1d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/297cb2458a96ea96d5e9d6ef38f1b7305c071f32", + "reference": "297cb2458a96ea96d5e9d6ef38f1b7305c071f32", "shasum": "" }, "require": { @@ -465,7 +465,7 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", - "time": "2020-01-26T23:36:48+00:00" + "time": "2020-02-04T22:30:27+00:00" } ], "aliases": [], From 4572ec8175b5050da2dc1e049a55d40f0be318ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 17:14:11 +0000 Subject: [PATCH 14/59] travis: run composer with --prefer-dist --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56c3327d1..c03120150 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,10 @@ before_script: - echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini script: - - composer install + - composer install --prefer-dist - ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G - ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit - - composer install --no-dev + - composer install --no-dev --prefer-dist - ./tests/travis.sh -t4 cache: From 262728b0911b5a0b9ac0129d1a8fbbde5200ec2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 18:31:51 +0000 Subject: [PATCH 15/59] PopulationTask: clean up overcomplicated garbage --- .../level/generator/PopulationTask.php | 32 +++---------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index 29c1f96df..95019457a 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -102,48 +102,26 @@ class PopulationTask extends AsyncTask{ } foreach($chunks as $c){ - if($c !== null){ - $manager->setChunk($c->getX(), $c->getZ(), $c); - if(!$c->isGenerated()){ - $generator->generateChunk($c->getX(), $c->getZ()); - $c = $manager->getChunk($c->getX(), $c->getZ()); - $c->setGenerated(); - } + $manager->setChunk($c->getX(), $c->getZ(), $c); + if(!$c->isGenerated()){ + $generator->generateChunk($c->getX(), $c->getZ()); + $c->setGenerated(); } } $generator->populateChunk($chunk->getX(), $chunk->getZ()); - $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->recalculateHeightMap(); $chunk->populateSkyLight(); $chunk->setLightPopulated(); $chunk->setPopulated(); $this->chunk = $chunk->fastSerialize(); - $manager->setChunk($chunk->getX(), $chunk->getZ(), null); - foreach($chunks as $i => $c){ - if($c !== null){ - $c = $chunks[$i] = $manager->getChunk($c->getX(), $c->getZ()); - if(!$c->hasChanged()){ - $chunks[$i] = null; - } - }else{ - //This way non-changed chunks are not set - $chunks[$i] = null; - } + $this->{"chunk$i"} = $c->hasChanged() ? $c->fastSerialize() : null; } $manager->cleanChunks(); - - for($i = 0; $i < 9; ++$i){ - if($i === 4){ - continue; - } - - $this->{"chunk$i"} = $chunks[$i] !== null ? $chunks[$i]->fastSerialize() : null; - } } public function onCompletion(Server $server){ From dfc8a6ffdd7755831e4e57fbdfbc054fa114a0c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 19:54:50 +0000 Subject: [PATCH 16/59] Player: remove useless code from save() --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 98a6109a3..c204496f4 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -3573,7 +3573,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->namedtag->setInt("playerGameType", $this->gamemode); $this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); - if($this->username != "" and $this->namedtag instanceof CompoundTag){ + if($this->username != ""){ $this->server->saveOfflinePlayerData($this->username, $this->namedtag); } } From 8cba2e0346b89d95e6da1633b87b3b8ee30c23eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 19:56:16 +0000 Subject: [PATCH 17/59] Server: fixed wrong non-nullability of queryHandler --- src/pocketmine/Server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 3c9a373be..ae84e70dc 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -320,8 +320,8 @@ class Server{ */ private $uniquePlayers = []; - /** @var QueryHandler */ - private $queryHandler; + /** @var QueryHandler|null */ + private $queryHandler = null; /** @var QueryRegenerateEvent */ private $queryRegenerateTask = null; From ecf662bf74e49a08ef0926936852a6c2b1122dcd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:31:01 +0000 Subject: [PATCH 18/59] Server: Lazy-init static sleeper as-needed this makes it testable without a server context. --- src/pocketmine/Server.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ae84e70dc..f2bfc3efd 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -186,7 +186,7 @@ class Server{ /** @var Server */ private static $instance = null; - /** @var \Threaded */ + /** @var \Threaded|null */ private static $sleeper = null; /** @var SleeperHandler */ @@ -1284,7 +1284,10 @@ class Server{ * @return void */ public static function microSleep(int $microseconds){ - Server::$sleeper->synchronized(function(int $ms) : void{ + if(self::$sleeper === null){ + self::$sleeper = new \Threaded(); + } + self::$sleeper->synchronized(function(int $ms) : void{ Server::$sleeper->wait($ms); }, $microseconds); } @@ -1294,7 +1297,6 @@ class Server{ throw new \InvalidStateException("Only one server instance can exist at once"); } self::$instance = $this; - self::$sleeper = new \Threaded; $this->tickSleeper = new SleeperHandler(); $this->autoloader = $autoloader; $this->logger = $logger; From 0d19f6c9681d45e1391cbc95b802f2bef1e84723 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:32:51 +0000 Subject: [PATCH 19/59] Server: initialize auto updater before loading plugins, not after from a plugin PoV, getUpdater() is always supposed to return an AutoUpdater instance, but it would return null during onLoad(), which is bad. --- src/pocketmine/Server.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f2bfc3efd..ca8087f86 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1522,10 +1522,9 @@ class Server{ $this->queryRegenerateTask = new QueryRegenerateEvent($this); - $this->pluginManager->loadPlugins($this->pluginPath); - $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); + $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginLoadOrder::STARTUP); $this->network->registerInterface(new RakLibInterface($this)); From faef4e873638995f263c35bf223692381b391090 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:33:27 +0000 Subject: [PATCH 20/59] SimpleCommandMap: Command->getLabel() never returns null --- src/pocketmine/command/SimpleCommandMap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index 1eb2c87df..02926d092 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -186,7 +186,7 @@ class SimpleCommandMap implements CommandMap{ return false; } - if(isset($this->knownCommands[$label]) and $this->knownCommands[$label]->getLabel() !== null and $this->knownCommands[$label]->getLabel() === $label){ + if(isset($this->knownCommands[$label]) and $this->knownCommands[$label]->getLabel() === $label){ return false; } From fe5620f09733932d30a0abc852239d168d8e01a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:36:44 +0000 Subject: [PATCH 21/59] ThreadManager: Lazy-init during getInstance() --- src/pocketmine/PocketMine.php | 1 - src/pocketmine/ThreadManager.php | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 745ad41f9..1dea85d2e 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -263,7 +263,6 @@ namespace pocketmine { //TODO: move this to a Server field define('pocketmine\START_TIME', microtime(true)); - ThreadManager::init(); /* * We now use the Composer autoloader, but this autoloader is still for loading plugins. diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/ThreadManager.php index 4d232c3fa..20c068b94 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/ThreadManager.php @@ -28,10 +28,11 @@ use function spl_object_hash; class ThreadManager extends \Volatile{ - /** @var ThreadManager */ + /** @var ThreadManager|null */ private static $instance = null; /** + * @deprecated * @return void */ public static function init(){ @@ -42,6 +43,9 @@ class ThreadManager extends \Volatile{ * @return ThreadManager */ public static function getInstance(){ + if(self::$instance === null){ + self::$instance = new ThreadManager(); + } return self::$instance; } From e1a61cb51add6ee767d0578630b7e230da225c56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:38:45 +0000 Subject: [PATCH 22/59] BaseLang: get() never returns null --- src/pocketmine/lang/BaseLang.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/lang/BaseLang.php b/src/pocketmine/lang/BaseLang.php index aa5eb6bb0..c869909f5 100644 --- a/src/pocketmine/lang/BaseLang.php +++ b/src/pocketmine/lang/BaseLang.php @@ -128,7 +128,7 @@ class BaseLang{ */ public function translateString(string $str, array $params = [], string $onlyPrefix = null) : string{ $baseText = $this->get($str); - $baseText = $this->parseTranslation(($baseText !== null and ($onlyPrefix === null or strpos($str, $onlyPrefix) === 0)) ? $baseText : $str, $onlyPrefix); + $baseText = $this->parseTranslation(($onlyPrefix === null or strpos($str, $onlyPrefix) === 0) ? $baseText : $str, $onlyPrefix); foreach($params as $i => $p){ $baseText = str_replace("{%$i}", $this->parseTranslation((string) $p), $baseText, $onlyPrefix); From 25554f0d61ec4e844e0392a19eb7f7ac690c1d8e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:39:38 +0000 Subject: [PATCH 23/59] Level: remove useless code from unload() --- src/pocketmine/level/Level.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 87d65c776..922916b4f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -612,8 +612,8 @@ class Level implements ChunkManager, Metadatable{ foreach($this->getPlayers() as $player){ if($this === $defaultLevel or $defaultLevel === null){ $player->close($player->getLeaveMessage(), "Forced default world unload"); - }elseif($defaultLevel instanceof Level){ - $player->teleport($this->server->getDefaultLevel()->getSafeSpawn()); + }else{ + $player->teleport($defaultLevel->getSafeSpawn()); } } From 914450c30b2b02db40a44df9454ae3ddeb81f8a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:40:34 +0000 Subject: [PATCH 24/59] Entity: remove useless assert() namedtag is always non-null here, and if it isn't, it should just catch fire the normal way. --- src/pocketmine/entity/Entity.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 0c511a9ad..cfb8be6b7 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -904,8 +904,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function initEntity() : void{ - assert($this->namedtag instanceof CompoundTag); - if($this->namedtag->hasTag("CustomName", StringTag::class)){ $this->setNameTag($this->namedtag->getString("CustomName")); From ac4f00be81d4c7ff3f5f4644315713df8bb17708 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:42:40 +0000 Subject: [PATCH 25/59] PluginManager: combine conditions into something less useless the left side was already implying that the var is a Plugin instance, but PHPStan doesn't like non-bool conditions in strict mode. --- src/pocketmine/plugin/PluginManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index a7450078d..c25eaccf3 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -332,7 +332,7 @@ class PluginManager{ if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){ unset($plugins[$name]); $loadedThisLoop++; - if($plugin = $this->loadPlugin($file, $loaders) and $plugin instanceof Plugin){ + if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ $loadedPlugins[$name] = $plugin; }else{ $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.genericLoadError", [$name])); From 2f325b8c91a720fbd67f25c563e6e2e35c393e71 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:43:40 +0000 Subject: [PATCH 26/59] Permission: loadPermission() never returns null --- src/pocketmine/permission/Permission.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pocketmine/permission/Permission.php b/src/pocketmine/permission/Permission.php index 536c955ed..d2c64d900 100644 --- a/src/pocketmine/permission/Permission.php +++ b/src/pocketmine/permission/Permission.php @@ -115,9 +115,7 @@ class Permission{ if(is_array($data["children"])){ foreach($data["children"] as $k => $v){ if(is_array($v)){ - if(($perm = self::loadPermission($k, $v, $default, $output)) !== null){ - $output[] = $perm; - } + $output[] = self::loadPermission($k, $v, $default, $output); } $children[$k] = true; } From e1ddf906954bf355a06a92c20e5d6198883ab706 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:44:27 +0000 Subject: [PATCH 27/59] Chunk: remove useless instanceof checks these are always CompoundTags, and if they aren't we have a bug somewhere else. --- src/pocketmine/level/format/Chunk.php | 40 ++++++++++++--------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 41de5a65a..1d7e294ac 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -687,23 +687,21 @@ class Chunk{ $level->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ - if($nbt instanceof CompoundTag){ - if(!$nbt->hasTag("id")){ //allow mixed types (because of leveldb) - $changed = true; - continue; - } + if(!$nbt->hasTag("id")){ //allow mixed types (because of leveldb) + $changed = true; + continue; + } - try{ - $entity = Entity::createEntity($nbt->getTag("id")->getValue(), $level, $nbt); - if(!($entity instanceof Entity)){ - $changed = true; - continue; - } - }catch(\Throwable $t){ - $level->getServer()->getLogger()->logException($t); + try{ + $entity = Entity::createEntity($nbt->getTag("id")->getValue(), $level, $nbt); + if(!($entity instanceof Entity)){ $changed = true; continue; } + }catch(\Throwable $t){ + $level->getServer()->getLogger()->logException($t); + $changed = true; + continue; } } $this->NBTentities = []; @@ -711,16 +709,14 @@ class Chunk{ $level->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ - if($nbt instanceof CompoundTag){ - if(!$nbt->hasTag(Tile::TAG_ID, StringTag::class)){ - $changed = true; - continue; - } + if(!$nbt->hasTag(Tile::TAG_ID, StringTag::class)){ + $changed = true; + continue; + } - if(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){ - $changed = true; - continue; - } + if(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){ + $changed = true; + continue; } } From 889cd5e206c76596a8ff3d464c1483f97bca4da6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:45:13 +0000 Subject: [PATCH 28/59] PlayerNetworkSessionAdapter: clean up leftovers from multi quote support for json decode --- .../network/mcpe/PlayerNetworkSessionAdapter.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index ab5e8df2e..59203e2f8 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -274,9 +274,9 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ $raw = $matches[1]; $lastComma = -1; $newParts = []; - $quoteType = null; + $inQuotes = false; for($i = 0, $len = strlen($raw); $i <= $len; ++$i){ - if($i === $len or ($raw[$i] === "," and $quoteType === null)){ + if($i === $len or ($raw[$i] === "," and !$inQuotes)){ $part = substr($raw, $lastComma + 1, $i - ($lastComma + 1)); if(trim($part) === ""){ //regular parts will have quotes or something else that makes them non-empty $part = '""'; @@ -284,13 +284,13 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ $newParts[] = $part; $lastComma = $i; }elseif($raw[$i] === '"'){ - if($quoteType === null){ - $quoteType = $raw[$i]; - }elseif($raw[$i] === $quoteType){ + if(!$inQuotes){ + $inQuotes = true; + }else{ $backslashes = 0; for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){} if(($backslashes % 2) === 0){ //unescaped quote - $quoteType = null; + $inQuotes = false; } } } From e689fd545b2903d68b2f6ebdf5a462607de3e084 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:48:54 +0000 Subject: [PATCH 29/59] PocketMine.php: avoid use of short ternary --- src/pocketmine/PocketMine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 1dea85d2e..1a5c1a1c4 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -173,7 +173,7 @@ namespace pocketmine { $opts = getopt("", ["bootstrap:"]); if(isset($opts["bootstrap"])){ - $bootstrap = realpath($opts["bootstrap"]) ?: $opts["bootstrap"]; + $bootstrap = ($real = realpath($opts["bootstrap"])) !== false ? $real : $opts["bootstrap"]; }else{ $bootstrap = dirname(__FILE__, 3) . '/vendor/autoload.php'; } From 41b1fa7b483115f7783b29d25ecab3124a21facd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:50:36 +0000 Subject: [PATCH 30/59] Config: clean up inconsistent data parsing & handling --- src/pocketmine/utils/Config.php | 38 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index c04e74fc7..5efd196c2 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -172,31 +172,30 @@ class Config{ }else{ if($this->correct){ $content = file_get_contents($this->file); + $config = null; switch($this->type){ case Config::PROPERTIES: - $this->parseProperties($content); + $config = $this->parseProperties($content); break; case Config::JSON: - $this->config = json_decode($content, true); + $config = json_decode($content, true); break; case Config::YAML: $content = self::fixYAMLIndexes($content); - $this->config = yaml_parse($content); + $config = yaml_parse($content); break; case Config::SERIALIZED: - $this->config = unserialize($content); + $config = unserialize($content); break; case Config::ENUM: - $this->parseList($content); + $config = self::parseList($content); break; default: $this->correct = false; return false; } - if(!is_array($this->config)){ - $this->config = $default; - } + $this->config = is_array($config) ? $config : $default; if($this->fillDefaults($default, $this->config) > 0){ $this->save(); } @@ -531,14 +530,20 @@ class Config{ return $changed; } - private function parseList(string $content) : void{ + /** + * @return true[] + * @phpstan-return array + */ + private static function parseList(string $content) : array{ + $result = []; foreach(explode("\n", trim(str_replace("\r\n", "\n", $content))) as $v){ $v = trim($v); if($v == ""){ continue; } - $this->config[$v] = true; + $result[$v] = true; } + return $result; } private function writeProperties() : string{ @@ -555,7 +560,12 @@ class Config{ return $content; } - private function parseProperties(string $content) : void{ + /** + * @return mixed[] + * @phpstan-return array + */ + private function parseProperties(string $content) : array{ + $result = []; if(preg_match_all('/^\s*([a-zA-Z0-9\-_\.]+)[ \t]*=([^\r\n]*)/um', $content, $matches) > 0){ //false or 0 matches foreach($matches[1] as $i => $k){ $v = trim($matches[2][$i]); @@ -571,11 +581,13 @@ class Config{ $v = false; break; } - if(isset($this->config[$k])){ + if(isset($result[$k])){ MainLogger::getLogger()->debug("[Config] Repeated property " . $k . " on file " . $this->file); } - $this->config[$k] = $v; + $result[$k] = $v; } } + + return $result; } } From 495bfda044dd074d6abf16a9ab6c71d3cab30f60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:53:54 +0000 Subject: [PATCH 31/59] Drop a bunch of invalid null defaults phpstan doesn't report these out of the box, for reasons I'm not clear on. It's also not clear if having null defaults has any effect on nullability behaviour, so they are best removed. In addition, these would be problematic on 7.4. --- src/pocketmine/Player.php | 4 ++-- src/pocketmine/Server.php | 18 +++++++++--------- src/pocketmine/block/BlockFactory.php | 16 ++++++++-------- src/pocketmine/item/ItemFactory.php | 2 +- src/pocketmine/level/Level.php | 2 +- .../network/mcpe/protocol/PacketPool.php | 2 +- src/pocketmine/permission/BanEntry.php | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c204496f4..c498cebee 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -286,7 +286,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var PlayerCursorInventory */ protected $cursorInventory; /** @var CraftingGrid */ - protected $craftingGrid = null; + protected $craftingGrid; /** @var CraftingTransaction|null */ protected $craftingTransaction = null; @@ -348,7 +348,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ protected $flying = false; /** @var PermissibleBase */ - private $perm = null; + private $perm; /** @var int|null */ protected $lineHeight = null; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ca8087f86..a32f67086 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -193,16 +193,16 @@ class Server{ private $tickSleeper; /** @var BanList */ - private $banByName = null; + private $banByName; /** @var BanList */ - private $banByIP = null; + private $banByIP; /** @var Config */ - private $operators = null; + private $operators; /** @var Config */ - private $whitelist = null; + private $whitelist; /** @var bool */ private $isRunning = true; @@ -211,13 +211,13 @@ class Server{ private $hasStopped = false; /** @var PluginManager */ - private $pluginManager = null; + private $pluginManager; /** @var float */ private $profilingTickRate = 20; /** @var AutoUpdater */ - private $updater = null; + private $updater; /** @var AsyncPool */ private $asyncPool; @@ -255,10 +255,10 @@ class Server{ private $memoryManager; /** @var CommandReader */ - private $console = null; + private $console; /** @var SimpleCommandMap */ - private $commandMap = null; + private $commandMap; /** @var CraftingManager */ private $craftingManager; @@ -324,7 +324,7 @@ class Server{ private $queryHandler = null; /** @var QueryRegenerateEvent */ - private $queryRegenerateTask = null; + private $queryRegenerateTask; /** @var Config */ private $properties; diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 68f42ea11..6e99fcf6d 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -33,22 +33,22 @@ use function min; */ class BlockFactory{ /** @var \SplFixedArray */ - private static $fullList = null; + private static $fullList; /** @var \SplFixedArray */ - public static $solid = null; + public static $solid; /** @var \SplFixedArray */ - public static $transparent = null; + public static $transparent; /** @var \SplFixedArray */ - public static $hardness = null; + public static $hardness; /** @var \SplFixedArray */ - public static $light = null; + public static $light; /** @var \SplFixedArray */ - public static $lightFilter = null; + public static $lightFilter; /** @var \SplFixedArray */ - public static $diffusesSkyLight = null; + public static $diffusesSkyLight; /** @var \SplFixedArray */ - public static $blastResistance = null; + public static $blastResistance; /** * Initializes the block factory. By default this is called only once on server start, however you may wish to use diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index ed9e969d4..0f933fd9c 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -47,7 +47,7 @@ class ItemFactory{ * @var \SplFixedArray * @phpstan-var \SplFixedArray */ - private static $list = null; + private static $list; /** * @return void diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 922916b4f..fa6201145 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -265,7 +265,7 @@ class Level implements ChunkManager, Metadatable{ /** @var bool */ private $clearChunksOnTick; /** @var \SplFixedArray */ - private $randomTickBlocks = null; + private $randomTickBlocks; /** @var LevelTimings */ public $timings; diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index cb4b919f4..3c8e3610e 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -28,7 +28,7 @@ use pocketmine\utils\BinaryDataException; class PacketPool{ /** @var \SplFixedArray */ - protected static $pool = null; + protected static $pool; /** * @return void diff --git a/src/pocketmine/permission/BanEntry.php b/src/pocketmine/permission/BanEntry.php index ddda2f511..d67399925 100644 --- a/src/pocketmine/permission/BanEntry.php +++ b/src/pocketmine/permission/BanEntry.php @@ -38,7 +38,7 @@ class BanEntry{ /** @var string */ private $name; /** @var \DateTime */ - private $creationDate = null; + private $creationDate; /** @var string */ private $source = "(Unknown)"; /** @var \DateTime|null */ From 1a5228e7a6effbf1b5ff3a3402ec7bc5b6f36730 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:55:03 +0000 Subject: [PATCH 32/59] Fixed property types with missing null PhpDoc types --- src/pocketmine/Server.php | 4 ++-- src/pocketmine/command/Command.php | 6 +++--- src/pocketmine/item/Item.php | 2 +- src/pocketmine/level/Explosion.php | 4 ++-- src/pocketmine/network/mcpe/protocol/DataPacket.php | 2 +- src/pocketmine/network/mcpe/protocol/LoginPacket.php | 4 ++-- src/pocketmine/permission/PermissibleBase.php | 2 +- src/pocketmine/permission/PermissionAttachment.php | 2 +- src/pocketmine/resourcepacks/ZippedResourcePack.php | 2 +- src/pocketmine/scheduler/AsyncTask.php | 2 +- src/pocketmine/timings/TimingsHandler.php | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index a32f67086..fdd3f9f81 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -183,7 +183,7 @@ class Server{ public const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin"; public const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user"; - /** @var Server */ + /** @var Server|null */ private static $instance = null; /** @var \Threaded|null */ @@ -346,7 +346,7 @@ class Server{ /** @var Level[] */ private $levels = []; - /** @var Level */ + /** @var Level|null */ private $levelDefault = null; public function getName() : string{ diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 3c9c5f7a2..4bb0352ef 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -65,11 +65,11 @@ abstract class Command{ /** @var string|null */ private $permission = null; - /** @var string */ + /** @var string|null */ private $permissionMessage = null; - /** @var TimingsHandler */ - public $timings; + /** @var TimingsHandler|null */ + public $timings = null; /** * @param string[] $aliases diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c469755bc..5ad333758 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -60,7 +60,7 @@ class Item implements ItemIds, \JsonSerializable{ public const TAG_DISPLAY_NAME = "Name"; public const TAG_DISPLAY_LORE = "Lore"; - /** @var LittleEndianNBTStream */ + /** @var LittleEndianNBTStream|null */ private static $cachedParser = null; private static function parseCompoundTag(string $tag) : CompoundTag{ diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 08b049661..a2f7684c6 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -60,14 +60,14 @@ class Explosion{ public $affectedBlocks = []; /** @var float */ public $stepLen = 0.3; - /** @var Entity|Block */ + /** @var Entity|Block|null */ private $what; /** @var SubChunkIteratorManager */ private $subChunkHandler; /** - * @param Entity|Block $what + * @param Entity|Block|null $what */ public function __construct(Position $center, float $size, $what = null){ if(!$center->isValid()){ diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index b329a179e..7f8aa2fb7 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -41,7 +41,7 @@ abstract class DataPacket extends NetworkBinaryStream{ /** @var bool */ public $isEncoded = false; - /** @var CachedEncapsulatedPacket */ + /** @var CachedEncapsulatedPacket|null */ public $__encapsulatedPacket = null; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index a8ad473bf..5e8a5a8ed 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -45,8 +45,8 @@ class LoginPacket extends DataPacket{ public $clientUUID; /** @var int */ public $clientId; - /** @var string */ - public $xuid; + /** @var string|null */ + public $xuid = null; /** @var string */ public $identityPublicKey; /** @var string */ diff --git a/src/pocketmine/permission/PermissibleBase.php b/src/pocketmine/permission/PermissibleBase.php index 0b7e44e52..f8f646931 100644 --- a/src/pocketmine/permission/PermissibleBase.php +++ b/src/pocketmine/permission/PermissibleBase.php @@ -32,7 +32,7 @@ class PermissibleBase implements Permissible{ /** @var ServerOperator */ private $opable; - /** @var Permissible */ + /** @var Permissible|null */ private $parent = null; /** @var PermissionAttachment[] */ diff --git a/src/pocketmine/permission/PermissionAttachment.php b/src/pocketmine/permission/PermissionAttachment.php index 2eb059461..6f8520edf 100644 --- a/src/pocketmine/permission/PermissionAttachment.php +++ b/src/pocketmine/permission/PermissionAttachment.php @@ -27,7 +27,7 @@ use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; class PermissionAttachment{ - /** @var PermissionRemovedExecutor */ + /** @var PermissionRemovedExecutor|null */ private $removed = null; /** @var bool[] */ diff --git a/src/pocketmine/resourcepacks/ZippedResourcePack.php b/src/pocketmine/resourcepacks/ZippedResourcePack.php index f0106573c..3a4ba556a 100644 --- a/src/pocketmine/resourcepacks/ZippedResourcePack.php +++ b/src/pocketmine/resourcepacks/ZippedResourcePack.php @@ -62,7 +62,7 @@ class ZippedResourcePack implements ResourcePack{ /** @var \stdClass */ protected $manifest; - /** @var string */ + /** @var string|null */ protected $sha256 = null; /** @var resource */ diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index fd4fa0e93..dc4723c58 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -53,7 +53,7 @@ abstract class AsyncTask extends Collectable{ */ private static $localObjectStorage; - /** @var AsyncWorker $worker */ + /** @var AsyncWorker|null $worker */ public $worker = null; /** @var \Threaded */ diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index a7e54101b..5538c070f 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -136,7 +136,7 @@ class TimingsHandler{ /** @var string */ private $name; - /** @var TimingsHandler */ + /** @var TimingsHandler|null */ private $parent = null; /** @var int */ From 4518d9d9ce89e350dd7d12ad869b34776e28549a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:55:58 +0000 Subject: [PATCH 33/59] Item: drop useless @var confusing PHPStan --- src/pocketmine/item/Item.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 5ad333758..bf3da2d9e 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -438,7 +438,6 @@ class Item implements ItemIds, \JsonSerializable{ return $this->clearCustomName(); } - /** @var CompoundTag $display */ $display = $this->getNamedTagEntry(self::TAG_DISPLAY); if(!($display instanceof CompoundTag)){ $display = new CompoundTag(self::TAG_DISPLAY); From 037c34d961979d0e2baae32da44cb01c477ea540 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 20:58:38 +0000 Subject: [PATCH 34/59] Living: fixed bad @var confusing PHPStan --- src/pocketmine/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 80aa45e50..09585fd24 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -111,7 +111,7 @@ abstract class Living extends Entity implements Damageable{ $this->setHealth($health); - /** @var CompoundTag[]|ListTag $activeEffectsTag */ + /** @var CompoundTag[]|ListTag|null */ $activeEffectsTag = $this->namedtag->getListTag("ActiveEffects"); if($activeEffectsTag !== null){ foreach($activeEffectsTag as $e){ From 34972c3327f099be2c692eb964172fe62a71df15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Feb 2020 21:00:56 +0000 Subject: [PATCH 35/59] Assume that getmypid() never returns false my background research on this informs me that this returns false on negative PID, which never happens because the underlying C API call never fails - not on linux, bsd, or windows. --- .../network/mcpe/protocol/types/RuntimeBlockMapping.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php index 3a6f5c54a..e9b5dc41c 100644 --- a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -123,7 +123,7 @@ final class RuntimeBlockMapping{ */ private static function randomizeTable(array $table) : array{ $postSeed = mt_rand(); //save a seed to set afterwards, to avoid poor quality randoms - mt_srand(getmypid() ?: 0); //Use a seed which is the same on all threads. This isn't a secure seed, but we don't care. + mt_srand(getmypid()); //Use a seed which is the same on all threads. This isn't a secure seed, but we don't care. shuffle($table); mt_srand($postSeed); //restore a good quality seed that isn't dependent on PID return $table; From 8f434b9edd8e1d82c09d055dd9ad644bd609d28c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2020 22:40:41 +0000 Subject: [PATCH 36/59] Bump adhocore/json-comment from 0.0.7 to 0.1.0 Bumps [adhocore/json-comment](https://github.com/adhocore/php-json-comment) from 0.0.7 to 0.1.0. - [Release notes](https://github.com/adhocore/php-json-comment/releases) - [Changelog](https://github.com/adhocore/php-json-comment/blob/master/CHANGELOG.md) - [Commits](https://github.com/adhocore/php-json-comment/compare/v0.0.7...0.1.0) Signed-off-by: dependabot-preview[bot] --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 42831b501..718811f22 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "pocketmine/classloader": "^0.1.0", "pocketmine/log": "^0.1.0", "daverandom/callback-validator": "dev-master", - "adhocore/json-comment": "^0.0.7" + "adhocore/json-comment": "^0.1.0" }, "require-dev": { "phpstan/phpstan": "^0.12.8", diff --git a/composer.lock b/composer.lock index c059b4290..c9b5c48b2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,27 +4,27 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e75353b6127ffbd846cdbad57b83a65f", + "content-hash": "1294d03ca688653618a4f1d58f5e4ec3", "packages": [ { "name": "adhocore/json-comment", - "version": "v0.0.7", + "version": "0.1.0", "source": { "type": "git", "url": "https://github.com/adhocore/php-json-comment.git", - "reference": "135356c7e7336ef59924f1d921c770045f937a76" + "reference": "8448076039389f558f39ad0553aab87db3f81614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/135356c7e7336ef59924f1d921c770045f937a76", - "reference": "135356c7e7336ef59924f1d921c770045f937a76", + "url": "https://api.github.com/repos/adhocore/php-json-comment/zipball/8448076039389f558f39ad0553aab87db3f81614", + "reference": "8448076039389f558f39ad0553aab87db3f81614", "shasum": "" }, "require": { "php": ">=5.4" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" + "phpunit/phpunit": "^6.5 || ^7.5" }, "type": "library", "autoload": { @@ -48,7 +48,7 @@ "json", "strip-comment" ], - "time": "2018-08-01T12:27:26+00:00" + "time": "2020-01-03T13:51:23+00:00" }, { "name": "daverandom/callback-validator", From e964dd2ca83fee20d92255b5d8ab30f16d53dd55 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 08:37:38 +0000 Subject: [PATCH 37/59] travis: cache composer vcs directory too --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c03120150..2fc68b387 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,5 +28,7 @@ script: cache: directories: - $HOME/.composer/cache/files + - $HOME/.composer/cache/vcs + notifications: email: false From e12618c7057fdbe0c345ba3be2242a4462754722 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 12:13:42 +0000 Subject: [PATCH 38/59] tests/phpunit: added missing native typehints --- tests/phpunit/inventory/BaseInventoryTest.php | 2 +- tests/phpunit/level/format/io/region/RegionLoaderTest.php | 4 ++-- tests/phpunit/network/mcpe/StupidJsonDecodeTest.php | 2 +- tests/phpunit/utils/UtilsTest.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index ade55f317..b4c836187 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -29,7 +29,7 @@ use pocketmine\item\ItemFactory; class BaseInventoryTest extends TestCase{ - public static function setUpBeforeClass(){ + public static function setUpBeforeClass() : void{ ItemFactory::init(); } diff --git a/tests/phpunit/level/format/io/region/RegionLoaderTest.php b/tests/phpunit/level/format/io/region/RegionLoaderTest.php index 5eed6482c..b156c2e57 100644 --- a/tests/phpunit/level/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/level/format/io/region/RegionLoaderTest.php @@ -38,7 +38,7 @@ class RegionLoaderTest extends TestCase{ /** @var RegionLoader */ private $region; - public function setUp(){ + public function setUp() : void{ $this->regionPath = sys_get_temp_dir() . '/test.testregion'; if(file_exists($this->regionPath)){ unlink($this->regionPath); @@ -47,7 +47,7 @@ class RegionLoaderTest extends TestCase{ $this->region->open(); } - public function tearDown(){ + public function tearDown() : void{ $this->region->close(); if(file_exists($this->regionPath)){ unlink($this->regionPath); diff --git a/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php b/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php index ac9940032..0bb6bb940 100644 --- a/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php +++ b/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php @@ -55,7 +55,7 @@ class StupidJsonDecodeTest extends TestCase{ * * @throws \ReflectionException */ - public function testStupidJsonDecode(string $brokenJson, $expect){ + public function testStupidJsonDecode(string $brokenJson, $expect) : void{ $decoded = ($this->stupidJsonDecodeFunc)($brokenJson, true); self::assertEquals($expect, $decoded); } diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index ae7844c44..be0cc7255 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -29,7 +29,7 @@ use function defined; class UtilsTest extends TestCase{ - public function setUp(){ + public function setUp() : void{ if(!defined('pocketmine\PATH')){ define('pocketmine\PATH', 'dummy'); } From 54ccc330d534c5df122ca703754baa37f15b1afb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2020 12:50:51 +0000 Subject: [PATCH 39/59] Bump irstea/phpunit-shim from 7.5.20 to 8.5.2 (#3296) --- composer.json | 2 +- composer.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 718811f22..c2e694880 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ }, "require-dev": { "phpstan/phpstan": "^0.12.8", - "irstea/phpunit-shim": "^7.5" + "irstea/phpunit-shim": "^8.5" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index c9b5c48b2..edff2d066 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": "1294d03ca688653618a4f1d58f5e4ec3", + "content-hash": "d8245ae04afc2a5b7a3c8f52ccd4f892", "packages": [ { "name": "adhocore/json-comment", @@ -382,11 +382,11 @@ "packages-dev": [ { "name": "irstea/phpunit-shim", - "version": "7.5.20", + "version": "8.5.2", "source": { "type": "git", "url": "https://gitlab.irstea.fr/pole-is/tools/phpunit-shim.git", - "reference": "81cd2d11e12165fddd2731033187dce4fbe8e013" + "reference": "39b6155954d6caec1110a9e78582c4816ab247bc" }, "require": { "ext-dom": "*", @@ -394,7 +394,8 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "php": "^7.1" + "ext-xmlwriter": "*", + "php": "^7.2" }, "replace": { "phpunit/phpunit": "self.version" @@ -426,7 +427,7 @@ "testing", "xunit" ], - "time": "2020-01-09T03:20:19+00:00" + "time": "2020-01-09T03:20:20+00:00" }, { "name": "phpstan/phpstan", From 532dc0fb6f434963c659b01627493a016f599d6a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 13:11:56 +0000 Subject: [PATCH 40/59] tests/phpunit: populate iterable types for phpstan --- tests/phpunit/block/BlockTest.php | 3 ++- tests/phpunit/item/ItemTest.php | 4 ++++ tests/phpunit/level/format/io/region/RegionLoaderTest.php | 4 ++++ tests/phpunit/network/mcpe/StupidJsonDecodeTest.php | 4 ++++ tests/phpunit/utils/ConfigTest.php | 7 ++++--- tests/phpunit/utils/UtilsTest.php | 4 ++++ 6 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 222a4cc6c..6c93e7488 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -95,7 +95,8 @@ class BlockTest extends TestCase{ } /** - * @return array + * @return int[][] + * @phpstan-return list */ public function blockGetProvider() : array{ return [ diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index b519dcaaa..d84449269 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -61,6 +61,10 @@ class ItemTest extends TestCase{ } } + /** + * @return mixed[][] + * @phpstan-return list + */ public function itemFromStringProvider() : array{ return [ ["dye:4", ItemIds::DYE, 4], diff --git a/tests/phpunit/level/format/io/region/RegionLoaderTest.php b/tests/phpunit/level/format/io/region/RegionLoaderTest.php index b156c2e57..87145144c 100644 --- a/tests/phpunit/level/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/level/format/io/region/RegionLoaderTest.php @@ -69,6 +69,10 @@ class RegionLoaderTest extends TestCase{ self::assertSame($data, $r->readChunk(0, 0)); } + /** + * @return \Generator|int[][] + * @phpstan-return \Generator + */ public function outOfBoundsCoordsProvider() : \Generator{ yield [-1, -1]; yield [32, 32]; diff --git a/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php b/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php index 0bb6bb940..4e1f3a749 100644 --- a/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php +++ b/tests/phpunit/network/mcpe/StupidJsonDecodeTest.php @@ -33,6 +33,10 @@ class StupidJsonDecodeTest extends TestCase{ $this->stupidJsonDecodeFunc = (new \ReflectionMethod(PlayerNetworkSessionAdapter::class, 'stupid_json_decode'))->getClosure(); } + /** + * @return mixed[][] + * @phpstan-return list + */ public function stupidJsonDecodeProvider() : array{ return [ ["[\n \"a\",\"b,c,d,e\\\" \",,0,1,2, false, 0.001]", ['a', 'b,c,d,e" ', '', 0, 1, 2, false, 0.001]], diff --git a/tests/phpunit/utils/ConfigTest.php b/tests/phpunit/utils/ConfigTest.php index 7c48562ec..3e1487358 100644 --- a/tests/phpunit/utils/ConfigTest.php +++ b/tests/phpunit/utils/ConfigTest.php @@ -28,7 +28,8 @@ use PHPUnit\Framework\TestCase; class ConfigTest extends TestCase{ /** - * @return \Generator + * @return \Generator|mixed[][] + * @phpstan-return \Generator */ public function fixYamlIndexesProvider() : \Generator{ yield ["x: 1\ny: 2\nz: 3\n", [ @@ -60,8 +61,8 @@ class ConfigTest extends TestCase{ /** * @dataProvider fixYamlIndexesProvider * - * @param string $test - * @param array $expected + * @param string $test + * @param mixed[] $expected */ public function testFixYamlIndexes(string $test, array $expected) : void{ $fixed = Config::fixYAMLIndexes($test); diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index be0cc7255..b020c682d 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -38,6 +38,10 @@ class UtilsTest extends TestCase{ } } + /** + * @return string[][] + * @phpstan-return list + */ public function parseDocCommentNewlineProvider() : array{ return [ ["\t/**\r\n\t * @param PlayerJoinEvent \$event\r\n\t * @priority HIGHEST\r\n\t * @notHandler\r\n\t */"], From 7885b54824bdfc13923b9e159314f23accf2495d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 13:13:12 +0000 Subject: [PATCH 41/59] phpstan: run static analysis on tests --- phpstan.neon.dist | 4 ++++ tests/phpstan/configs/php-bugs.neon | 3 +++ tests/phpstan/configs/phpunit-wiring-tests.neon | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 tests/phpstan/configs/php-bugs.neon create mode 100644 tests/phpstan/configs/phpunit-wiring-tests.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 28b369554..631a1f539 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,7 +2,9 @@ includes: - tests/phpstan/configs/com-dotnet-magic.neon - tests/phpstan/configs/custom-leveldb.neon - tests/phpstan/configs/gc-hacks.neon + - tests/phpstan/configs/php-bugs.neon - tests/phpstan/configs/phpstan-bugs.neon + - tests/phpstan/configs/phpunit-wiring-tests.neon - tests/phpstan/configs/pthreads-bugs.neon - tests/phpstan/configs/runtime-type-checks.neon @@ -13,10 +15,12 @@ parameters: - src/pocketmine/PocketMine.php - build/make-release.php - build/server-phar.php + - vendor/irstea/phpunit-shim/phpunit paths: - src - build/make-release.php - build/server-phar.php + - tests/phpunit dynamicConstantNames: - pocketmine\IS_DEVELOPMENT_BUILD - pocketmine\DEBUG diff --git a/tests/phpstan/configs/php-bugs.neon b/tests/phpstan/configs/php-bugs.neon new file mode 100644 index 000000000..0f82334e1 --- /dev/null +++ b/tests/phpstan/configs/php-bugs.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - "#^Method ReflectionMethod\\:\\:getClosure\\(\\) invoked with 0 parameters, 1 required\\.$#" diff --git a/tests/phpstan/configs/phpunit-wiring-tests.neon b/tests/phpstan/configs/phpunit-wiring-tests.neon new file mode 100644 index 000000000..11f82d563 --- /dev/null +++ b/tests/phpstan/configs/phpunit-wiring-tests.neon @@ -0,0 +1,6 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\level\\\\format\\\\io\\\\LevelProviderManager\\:\\:addProvider\\(\\) expects class\\-string\\, string given\\.$#" + count: 2 + path: ../../phpunit/level/format/io/LevelProviderManagerTest.php From 5ad66c3c9b15ca85be254f51c7e47ab8481e9b65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 13:21:39 +0000 Subject: [PATCH 42/59] BlockTest: throw exception instead of always-false assert --- tests/phpunit/block/BlockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 6c93e7488..5dc6f944d 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -62,7 +62,7 @@ class BlockTest extends TestCase{ } } - self::assertTrue(false, "Can't test registering new blocks because no unused spaces left"); + throw new \RuntimeException("Can't test registering new blocks because no unused spaces left"); } /** From 3a5709bf5e30d298a55aace94078c45c9b3b7784 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 13:23:18 +0000 Subject: [PATCH 43/59] start using phpstan-phpunit not using extension-installer because I want to part-integrate phpstan-strict-rules later on. --- composer.json | 3 ++- composer.lock | 58 ++++++++++++++++++++++++++++++++++++++++++++++- phpstan.neon.dist | 2 ++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c2e694880..3579c4dab 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ }, "require-dev": { "phpstan/phpstan": "^0.12.8", - "irstea/phpunit-shim": "^8.5" + "irstea/phpunit-shim": "^8.5", + "phpstan/phpstan-phpunit": "^0.12.6" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index edff2d066..dd690eca4 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": "d8245ae04afc2a5b7a3c8f52ccd4f892", + "content-hash": "82c757af39ed282d0d329dcd3053d045", "packages": [ { "name": "adhocore/json-comment", @@ -467,6 +467,62 @@ ], "description": "PHPStan - PHP Static Analysis Tool", "time": "2020-02-04T22:30:27+00:00" + }, + { + "name": "phpstan/phpstan-phpunit", + "version": "0.12.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-phpunit.git", + "reference": "26394996368b6d033d012547d3197f4e07e23021" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/26394996368b6d033d012547d3197f4e07e23021", + "reference": "26394996368b6d033d012547d3197f4e07e23021", + "shasum": "" + }, + "require": { + "php": "~7.1", + "phpstan/phpstan": "^0.12.4" + }, + "conflict": { + "phpunit/phpunit": "<7.0" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0", + "satooshi/php-coveralls": "^1.0", + "slevomat/coding-standard": "^4.7.2" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + }, + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPUnit extensions and rules for PHPStan", + "time": "2020-01-10T12:07:21+00:00" } ], "aliases": [], diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 631a1f539..ef316e5c4 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,6 +7,8 @@ includes: - tests/phpstan/configs/phpunit-wiring-tests.neon - tests/phpstan/configs/pthreads-bugs.neon - tests/phpstan/configs/runtime-type-checks.neon + - vendor/phpstan/phpstan-phpunit/extension.neon + - vendor/phpstan/phpstan-phpunit/rules.neon parameters: level: 6 From 70eb41470c9c75c6688ad6fe03816716637618b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 14:19:33 +0000 Subject: [PATCH 44/59] ContainerInventory: remove redundant check --- src/pocketmine/inventory/ContainerInventory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 7999ad54c..747c4c379 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -50,7 +50,7 @@ abstract class ContainerInventory extends BaseInventory{ if($holder instanceof Entity){ $pk->entityUniqueId = $holder->getId(); - }elseif($holder instanceof Vector3){ + }else{ $pk->x = $holder->getFloorX(); $pk->y = $holder->getFloorY(); $pk->z = $holder->getFloorZ(); From 86fc33fe265619b480e4a31c35da1e64cb9d4096 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 14:20:19 +0000 Subject: [PATCH 45/59] Level: add phpstan generics to getNearestEntity() --- src/pocketmine/level/Level.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index fa6201145..e03f791da 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2026,8 +2026,11 @@ class Level implements ChunkManager, Metadatable{ * * @param string $entityType Class of entity to use for instanceof * @param bool $includeDead Whether to include entitites which are dead + * @phpstan-template TEntity of Entity + * @phpstan-param class-string $entityType * * @return Entity|null an entity of type $entityType, or null if not found + * @phpstan-return TEntity */ public function getNearestEntity(Vector3 $pos, float $maxDistance, string $entityType = Entity::class, bool $includeDead = false) : ?Entity{ assert(is_a($entityType, Entity::class, true)); @@ -2039,7 +2042,10 @@ class Level implements ChunkManager, Metadatable{ $currentTargetDistSq = $maxDistance ** 2; - /** @var Entity|null $currentTarget */ + /** + * @var Entity|null $currentTarget + * @phpstan-var TEntity|null $currentTarget + */ $currentTarget = null; for($x = $minX; $x <= $maxX; ++$x){ From 1bdc61dd5feb0726fd1fdc6b771496c3d31ef1bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 14:24:57 +0000 Subject: [PATCH 46/59] Ore: do not destroy outer scope vars in for loops --- src/pocketmine/level/generator/object/Ore.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 182ba49ac..92d968395 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -75,24 +75,24 @@ class Ore{ $endY = (int) ($seedY + $size); $endZ = (int) ($seedZ + $size); - for($x = $startX; $x <= $endX; ++$x){ - $sizeX = ($x + 0.5 - $seedX) / $size; + for($xx = $startX; $xx <= $endX; ++$xx){ + $sizeX = ($xx + 0.5 - $seedX) / $size; $sizeX *= $sizeX; if($sizeX < 1){ - for($y = $startY; $y <= $endY; ++$y){ - $sizeY = ($y + 0.5 - $seedY) / $size; + for($yy = $startY; $yy <= $endY; ++$yy){ + $sizeY = ($yy + 0.5 - $seedY) / $size; $sizeY *= $sizeY; - if($y > 0 and ($sizeX + $sizeY) < 1){ - for($z = $startZ; $z <= $endZ; ++$z){ - $sizeZ = ($z + 0.5 - $seedZ) / $size; + if($yy > 0 and ($sizeX + $sizeY) < 1){ + for($zz = $startZ; $zz <= $endZ; ++$zz){ + $sizeZ = ($zz + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($x, $y, $z) === Block::STONE){ - $level->setBlockIdAt($x, $y, $z, $this->type->material->getId()); + if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($xx, $yy, $zz) === Block::STONE){ + $level->setBlockIdAt($xx, $yy, $zz, $this->type->material->getId()); if($this->type->material->getDamage() !== 0){ - $level->setBlockDataAt($x, $y, $z, $this->type->material->getDamage()); + $level->setBlockDataAt($xx, $yy, $zz, $this->type->material->getDamage()); } } } From 812424a61948b61de120873c54ffb0f841ac4d8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 14:26:03 +0000 Subject: [PATCH 47/59] GroundCover: drop useless variable in calculating startY --- src/pocketmine/level/generator/populator/GroundCover.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 08cd1c5d2..7858bd2dc 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -47,13 +47,13 @@ class GroundCover extends Populator{ } $column = $chunk->getBlockIdColumn($x, $z); - $y = 127; - for(; $y > 0; --$y){ - if($column[$y] !== "\x00" and !BlockFactory::get(ord($column[$y]))->isTransparent()){ + $startY = 127; + for(; $startY > 0; --$startY){ + if($column[$startY] !== "\x00" and !BlockFactory::get(ord($column[$startY]))->isTransparent()){ break; } } - $startY = min(127, $y + $diffY); + $startY = min(127, $startY + $diffY); $endY = $startY - count($cover); for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; From d26fcf7dee9dadf451f25067124044ded6a86544 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 15:58:27 +0000 Subject: [PATCH 48/59] Removed useless casts() from min/max calls --- src/pocketmine/MemoryManager.php | 2 +- src/pocketmine/Server.php | 2 +- src/pocketmine/command/defaults/HelpCommand.php | 2 +- src/pocketmine/entity/Human.php | 2 +- src/pocketmine/entity/utils/ExperienceUtils.php | 2 +- src/pocketmine/network/rcon/RCON.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 63d1db83c..20ec90997 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -181,7 +181,7 @@ class MemoryManager{ * Returns the allowed chunk radius based on the current memory usage. */ public function getViewDistance(int $distance) : int{ - return ($this->lowMemory and $this->lowMemChunkRadiusOverride > 0) ? (int) min($this->lowMemChunkRadiusOverride, $distance) : $distance; + return ($this->lowMemory and $this->lowMemChunkRadiusOverride > 0) ? min($this->lowMemChunkRadiusOverride, $distance) : $distance; } /** diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index fdd3f9f81..f3c399ad3 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1388,7 +1388,7 @@ class Server{ $poolSize = max(1, (int) $poolSize); } - $this->asyncPool = new AsyncPool($this, $poolSize, (int) max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); + $this->asyncPool = new AsyncPool($this, $poolSize, max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); if($this->getProperty("network.batch-threshold", 256) >= 0){ Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); diff --git a/src/pocketmine/command/defaults/HelpCommand.php b/src/pocketmine/command/defaults/HelpCommand.php index c4bf73f44..5e761d180 100644 --- a/src/pocketmine/command/defaults/HelpCommand.php +++ b/src/pocketmine/command/defaults/HelpCommand.php @@ -82,7 +82,7 @@ class HelpCommand extends VanillaCommand{ } ksort($commands, SORT_NATURAL | SORT_FLAG_CASE); $commands = array_chunk($commands, $pageHeight); - $pageNumber = (int) min(count($commands), $pageNumber); + $pageNumber = min(count($commands), $pageNumber); if($pageNumber < 1){ $pageNumber = 1; } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 130dfec8d..9049024f6 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -524,7 +524,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ public function getXpDropAmount() : int{ //this causes some XP to be lost on death when above level 1 (by design), dropping at most enough points for //about 7.5 levels of XP. - return (int) min(100, 7 * $this->getXpLevel()); + return min(100, 7 * $this->getXpLevel()); } /** diff --git a/src/pocketmine/entity/utils/ExperienceUtils.php b/src/pocketmine/entity/utils/ExperienceUtils.php index 3e4f4f74e..9b387b397 100644 --- a/src/pocketmine/entity/utils/ExperienceUtils.php +++ b/src/pocketmine/entity/utils/ExperienceUtils.php @@ -75,6 +75,6 @@ abstract class ExperienceUtils{ $x = Math::solveQuadratic($a, $b, $c - $xp); - return (float) max($x); //we're only interested in the positive solution + return max($x); //we're only interested in the positive solution } } diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 8da98c165..617f2ea9c 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -94,7 +94,7 @@ class RCON{ $this->server->getTickSleeper()->addNotifier($notifier, function() : void{ $this->check(); }); - $this->instance = new RCONInstance($this->socket, $password, (int) max(1, $maxClients), $this->server->getLogger(), $this->ipcThreadSocket, $notifier); + $this->instance = new RCONInstance($this->socket, $password, max(1, $maxClients), $this->server->getLogger(), $this->ipcThreadSocket, $notifier); socket_getsockname($this->socket, $addr, $port); $this->server->getLogger()->info("RCON running on $addr:$port"); From da3742b39eb77dd0d9477adc7a08161fc63b3ab7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 15:58:52 +0000 Subject: [PATCH 49/59] Remove useless typecasts --- src/pocketmine/command/defaults/EffectCommand.php | 2 +- src/pocketmine/entity/object/Painting.php | 4 ++-- src/pocketmine/level/Explosion.php | 2 +- src/pocketmine/level/generator/Flat.php | 4 ++-- src/pocketmine/network/mcpe/NetworkBinaryStream.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 55d94f992..3da54604a 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -76,7 +76,7 @@ class EffectCommand extends VanillaCommand{ } if($effect === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [(string) $args[1]])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [$args[1]])); return true; } diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 0fba4c6e1..f9767b211 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -83,8 +83,8 @@ class Painting extends Entity{ $this->namedtag->setInt("TileY", (int) $this->blockIn->y); $this->namedtag->setInt("TileZ", (int) $this->blockIn->z); - $this->namedtag->setByte("Facing", (int) $this->direction); - $this->namedtag->setByte("Direction", (int) $this->direction); //Save both for full compatibility + $this->namedtag->setByte("Facing", $this->direction); + $this->namedtag->setByte("Direction", $this->direction); //Save both for full compatibility $this->namedtag->setString("Motive", $this->motive); } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index a2f7684c6..4af974365 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -100,7 +100,7 @@ class Explosion{ $currentChunk = null; $currentSubChunk = null; - $mRays = (int) ($this->rays - 1); + $mRays = $this->rays - 1; for($i = 0; $i < $this->rays; ++$i){ for($j = 0; $j < $this->rays; ++$j){ for($k = 0; $k < $this->rays; ++$k){ diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index ca05f7438..24c4888d3 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -134,9 +134,9 @@ class Flat extends Generator{ protected function parsePreset() : void{ $preset = explode(";", $this->preset); - $blocks = (string) ($preset[1] ?? ""); + $blocks = $preset[1] ?? ""; $this->biome = (int) ($preset[2] ?? 1); - $options = (string) ($preset[3] ?? ""); + $options = $preset[3] ?? ""; $this->structure = self::parseLayers($blocks); $this->floorLevel = count($this->structure); diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index f197ac3b7..0e8831e6b 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -535,7 +535,7 @@ class NetworkBinaryStream extends BinaryStream{ } public function getByteRotation() : float{ - return (float) ($this->getByte() * (360 / 256)); + return ($this->getByte() * (360 / 256)); } public function putByteRotation(float $rotation) : void{ From 79acaa32533bd318cd41bc4a9e548f14d2cab258 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 16:06:58 +0000 Subject: [PATCH 50/59] Utils: remove useless typecasts --- src/pocketmine/utils/Utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index ad3ff0b0b..6ebe2ae7d 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -543,7 +543,7 @@ class Utils{ } switch(Utils::getOS()){ case "win": - exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL"); + exec("taskkill.exe /F /PID $pid > NUL"); break; case "mac": case "linux": @@ -551,7 +551,7 @@ class Utils{ if(function_exists("posix_kill")){ posix_kill($pid, 9); //SIGKILL }else{ - exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); + exec("kill -9 $pid > /dev/null 2>&1"); } } } From 0ec869932f968e8bb883b3b7951d708cb9a4ea35 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 17:59:05 +0000 Subject: [PATCH 51/59] Item: clean up internal NBT storage, discard useless legacy network cache this will now bail if the NBT string given is invalid upon setCompoundTag(), rather than shitting the bed when it's accessed. --- src/pocketmine/item/Item.php | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index bf3da2d9e..f4f781379 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -195,10 +195,8 @@ class Item implements ItemIds, \JsonSerializable{ protected $id; /** @var int */ protected $meta; - /** @var string */ - private $tags = ""; /** @var CompoundTag|null */ - private $cachedNBT = null; + private $nbt = null; /** @var int */ public $count = 1; /** @var string */ @@ -221,7 +219,8 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * Sets the Item's NBT + * @deprecated This method accepts NBT serialized in a network-dependent format. + * @see Item::setNamedTag() * * @param CompoundTag|string|null $tags * @@ -230,9 +229,10 @@ class Item implements ItemIds, \JsonSerializable{ public function setCompoundTag($tags) : Item{ if($tags instanceof CompoundTag){ $this->setNamedTag($tags); + }elseif(is_string($tags) and strlen($tags) > 0){ + $this->setNamedTag(self::parseCompoundTag($tags)); }else{ - $this->tags = $tags === null ? "" : (string) $tags; - $this->cachedNBT = null; + $this->clearNamedTag(); } return $this; @@ -245,14 +245,14 @@ class Item implements ItemIds, \JsonSerializable{ * Returns the serialized NBT of the Item */ public function getCompoundTag() : string{ - return $this->tags; + return $this->nbt !== null ? self::writeCompoundTag($this->nbt) : ""; } /** * Returns whether this Item has a non-empty NBT. */ public function hasCompoundTag() : bool{ - return $this->tags !== ""; + return $this->nbt !== null and $this->nbt->getCount() > 0; } public function hasCustomBlockData() : bool{ @@ -520,11 +520,7 @@ class Item implements ItemIds, \JsonSerializable{ * object is returned to allow the caller to manipulate and apply back to the item. */ public function getNamedTag() : CompoundTag{ - if(!$this->hasCompoundTag() and $this->cachedNBT === null){ - $this->cachedNBT = new CompoundTag(); - } - - return $this->cachedNBT ?? ($this->cachedNBT = self::parseCompoundTag($this->tags)); + return $this->nbt ?? ($this->nbt = new CompoundTag()); } /** @@ -537,8 +533,7 @@ class Item implements ItemIds, \JsonSerializable{ return $this->clearNamedTag(); } - $this->cachedNBT = $tag; - $this->tags = self::writeCompoundTag($tag); + $this->nbt = clone $tag; return $this; } @@ -548,7 +543,8 @@ class Item implements ItemIds, \JsonSerializable{ * @return $this */ public function clearNamedTag() : Item{ - return $this->setCompoundTag(""); + $this->nbt = null; + return $this; } public function getCount() : int{ @@ -888,6 +884,8 @@ class Item implements ItemIds, \JsonSerializable{ } public function __clone(){ - $this->cachedNBT = null; + if($this->nbt !== null){ + $this->nbt = clone $this->nbt; + } } } From a1622fa34506a809b2f84e42b05d561015c306e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 18:53:05 +0000 Subject: [PATCH 52/59] UtilsTest: silence a phpstan-strict-rules warning --- tests/phpunit/utils/UtilsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index b020c682d..a1a64dd57 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -65,6 +65,6 @@ class UtilsTest extends TestCase{ public function testNamespacedNiceClosureName() : void{ //be careful with this test. The closure has to be declared on the same line as the assertion. - self::assertSame('closure@' . Utils::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function(){})); + self::assertSame('closure@' . Utils::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function() : void{})); } } From 4e693e91e6dc1c340cacb2a3da4f083fd69199de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 19:22:27 +0000 Subject: [PATCH 53/59] ChestInventory: document that getHolder() may return Position there is a variance issue with EnderChestInventory that was detected by phpstan-strict-rules which can't be addressed without a BC break. This fix will at least allow static analysers to be aware that code using this function might catch fire when it sees an EnderChestInventory without realizing it. --- src/pocketmine/inventory/ChestInventory.php | 3 ++- src/pocketmine/inventory/DoubleChestInventory.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index 3e37e91b7..b7cd3765e 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\level\Position; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\types\WindowTypes; @@ -53,7 +54,7 @@ class ChestInventory extends ContainerInventory{ /** * This override is here for documentation and code completion purposes only. - * @return Chest + * @return Chest|Position */ public function getHolder(){ return $this->holder; diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index ca55d59e4..bf91477db 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\item\Item; +use pocketmine\level\Position; use pocketmine\Player; use pocketmine\tile\Chest; use function array_merge; @@ -56,7 +57,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ } /** - * @return Chest + * @return Chest|Position */ public function getHolder(){ return $this->left->getHolder(); From 213bf8366a58d73c3a1005b5a12bee6381bb1474 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 19:22:53 +0000 Subject: [PATCH 54/59] TranslationContainer: fix parameter type of setParameters() --- src/pocketmine/lang/TranslationContainer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/lang/TranslationContainer.php b/src/pocketmine/lang/TranslationContainer.php index 149864b87..b540d058e 100644 --- a/src/pocketmine/lang/TranslationContainer.php +++ b/src/pocketmine/lang/TranslationContainer.php @@ -65,7 +65,7 @@ class TranslationContainer extends TextContainer{ } /** - * @param string[] $params + * @param (float|int|string)[] $params * * @return void */ From 25bc95cd1e611924cd20abf85889165eaaf10d26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 19:23:11 +0000 Subject: [PATCH 55/59] removing more unnecessary casts --- src/pocketmine/network/mcpe/RakLibInterface.php | 2 +- src/pocketmine/permission/PermissionAttachment.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 0b73291df..c9d28370c 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -223,7 +223,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ * @return void */ public function setPortCheck($name){ - $this->interface->sendOption("portChecking", (bool) $name); + $this->interface->sendOption("portChecking", $name); } public function handleOption(string $option, string $value) : void{ diff --git a/src/pocketmine/permission/PermissionAttachment.php b/src/pocketmine/permission/PermissionAttachment.php index 6f8520edf..623282946 100644 --- a/src/pocketmine/permission/PermissionAttachment.php +++ b/src/pocketmine/permission/PermissionAttachment.php @@ -95,7 +95,7 @@ class PermissionAttachment{ */ public function setPermissions(array $permissions){ foreach($permissions as $key => $value){ - $this->permissions[$key] = (bool) $value; + $this->permissions[$key] = $value; } $this->permissible->recalculatePermissions(); } From 6c7dada2329642baa00606c5122a7dbe740fa3ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 19:44:10 +0000 Subject: [PATCH 56/59] finally, integrate phpstan-strict-rules --- composer.json | 3 +- composer.lock | 53 +++++++++++++- phpstan.neon.dist | 70 +++++++++++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 24 +++++++ .../phpstan/configs/runtime-type-checks.neon | 51 ++++++++++++++ 5 files changed, 199 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 3579c4dab..89694fca9 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "require-dev": { "phpstan/phpstan": "^0.12.8", "irstea/phpunit-shim": "^8.5", - "phpstan/phpstan-phpunit": "^0.12.6" + "phpstan/phpstan-phpunit": "^0.12.6", + "phpstan/phpstan-strict-rules": "^0.12.2" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index dd690eca4..6b9ed7cdd 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": "82c757af39ed282d0d329dcd3053d045", + "content-hash": "3bc1131c6ecd44aef9d1043f49563a6a", "packages": [ { "name": "adhocore/json-comment", @@ -523,6 +523,57 @@ ], "description": "PHPUnit extensions and rules for PHPStan", "time": "2020-01-10T12:07:21+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "0.12.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/a670a59aff7cf96f75d21b974860ada10e25b2ee", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee", + "shasum": "" + }, + "require": { + "php": "~7.1", + "phpstan/phpstan": "^0.12.6" + }, + "require-dev": { + "consistence/coding-standard": "^3.0.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.5.2" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + }, + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "time": "2020-01-20T13:08:52+00:00" } ], "aliases": [], diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ef316e5c4..8bfdcfc29 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -9,6 +9,7 @@ includes: - tests/phpstan/configs/runtime-type-checks.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon + - vendor/phpstan/phpstan-strict-rules/rules.neon parameters: level: 6 @@ -31,11 +32,50 @@ parameters: - tests/phpstan/stubs/chunkutils.stub reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings ignoreErrors: + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/CrashDump.php + + - + message: "#^pocketmine\\\\Player\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\entity\\\\Human\\.$#" + count: 1 + path: src/pocketmine/Player.php + - message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#" count: 1 path: src/pocketmine/Server.php + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\scheduler\\\\AsyncPool and pocketmine\\\\scheduler\\\\AsyncPool will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\command\\\\CommandReader and pocketmine\\\\command\\\\CommandReader will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^Instanceof between pocketmine\\\\network\\\\Network and pocketmine\\\\network\\\\Network will always evaluate to true\\.$#" + count: 1 + path: src/pocketmine/Server.php + + - + message: "#^pocketmine\\\\block\\\\[A-Za-z\\d]+\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\block\\\\Block\\.$#" + path: src/pocketmine/block + + - + message: "#^pocketmine\\\\block\\\\Block\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\level\\\\Position\\.$#" + count: 1 + path: src/pocketmine/block/Block.php + - message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" count: 1 @@ -77,6 +117,31 @@ parameters: count: 1 path: src/pocketmine/event/entity/ProjectileLaunchEvent.php + - + message: "#^pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" + count: 1 + path: src/pocketmine/inventory/DoubleChestInventory.php + + - + message: "#^pocketmine\\\\inventory\\\\EnderChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" + count: 1 + path: src/pocketmine/inventory/EnderChestInventory.php + + - + message: "#^pocketmine\\\\item\\\\GoldenAppleEnchanted\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\GoldenApple\\.$#" + count: 1 + path: src/pocketmine/item/GoldenAppleEnchanted.php + + - + message: "#^pocketmine\\\\item\\\\WrittenBook\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\WritableBook\\.$#" + count: 1 + path: src/pocketmine/item/WrittenBook.php + + - + message: "#^Variable property access on \\$this\\(pocketmine\\\\level\\\\generator\\\\PopulationTask\\)\\.$#" + count: 4 + path: src/pocketmine/level/generator/PopulationTask.php + - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" count: 1 @@ -87,6 +152,11 @@ parameters: count: 1 path: src/pocketmine/level/generator/normal/Normal.php + - + message: "#^Variable method call on pocketmine\\\\event\\\\Listener\\.$#" + count: 1 + path: src/pocketmine/plugin/MethodEventExecutor.php + - message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 66206c073..bdbce964d 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,5 +1,6 @@ parameters: ignoreErrors: + - "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" - message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" path: ../../../src @@ -33,7 +34,30 @@ parameters: count: 1 path: ../../../src/pocketmine/block/Liquid.php + - + #readline() may return false + message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/command/CommandReader.php + + - + #generics corruption, this might show up in other forms too + message: "#^Parameter \\#1 \\$offset \\(int\\) of method pocketmine\\\\entity\\\\AttributeMap\\:\\:offsetGet\\(\\) should be contravariant with parameter \\$offset \\(mixed\\) of method ArrayAccess\\\\:\\:offsetGet\\(\\)$#" + count: 1 + path: ../../../src/pocketmine/entity/AttributeMap.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 path: ../../../src/pocketmine/entity/projectile/Projectile.php + + - + message: "#^Call to function method_exists\\(\\) with pocketmine\\\\network\\\\mcpe\\\\CachedEncapsulatedPacket and '__toString' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/network/mcpe/protocol/DataPacket.php + + - + #phpstan doesn't understand that SplFixedArray may contain null + message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNotNull\\(\\) with int and string will always evaluate to true\\.$#" + count: 1 + path: ../../../tests/phpunit/block/BlockTest.php diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 7d48cacd9..59776a047 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -1,11 +1,31 @@ parameters: ignoreErrors: + - + message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\level…' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/Server.php + - #::add() / ::remove() thread parameter message: "#^If condition is always true\\.$#" count: 2 path: ../../../src/pocketmine/ThreadManager.php + - + message: "#^Instanceof between pocketmine\\\\Worker and pocketmine\\\\Worker will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/ThreadManager.php + + - + message: "#^Instanceof between pocketmine\\\\plugin\\\\RegisteredListener and pocketmine\\\\plugin\\\\RegisteredListener will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/event/HandlerList.php + + - + #jsonDeserialize(), not currently validated + message: "#^Casting to int something that's already int\\.$#" + count: 3 + path: ../../../src/pocketmine/item/Item.php - #::get() tags parameter message: "#^If condition is always false\\.$#" @@ -24,8 +44,39 @@ parameters: count: 1 path: ../../../src/pocketmine/item/ItemFactory.php + - + message: "#^Call to function is_object\\(\\) with \\*NEVER\\* will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/item/ItemFactory.php + - #->sendBlocks() blocks parameter message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 2 path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Instanceof between pocketmine\\\\math\\\\Vector3 and pocketmine\\\\math\\\\Vector3 will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function is_object\\(\\) with \\*NEVER\\* will always evaluate to true\\.$#" + count: 2 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/level/Level.php + + - + message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\level…' will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/level/generator/GeneratorManager.php + + - + #commands plugin.yml not currently validated, can't be sure + message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" + count: 1 + path: ../../../src/pocketmine/plugin/PluginManager.php From 9b02b8e51ef4fefc5a052faf664544e5995eb4f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 20:09:13 +0000 Subject: [PATCH 57/59] Item: do not compare serialized NBT in equals() this isn't cached anymore, and would be a performance drag. It would be nice to have some kind of fast path for this, but comparing NBT binary isn't it. --- src/pocketmine/item/Item.php | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index f4f781379..1d9e69af2 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -735,20 +735,9 @@ class Item implements ItemIds, \JsonSerializable{ * @param bool $checkCompound Whether to verify that the items' NBT match. */ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ - if($this->id === $item->getId() and (!$checkDamage or $this->getDamage() === $item->getDamage())){ - if($checkCompound){ - if($item->getCompoundTag() === $this->getCompoundTag()){ - return true; - }elseif($this->hasCompoundTag() and $item->hasCompoundTag()){ - //Serialized NBT didn't match, check the cached object tree. - return $this->getNamedTag()->equals($item->getNamedTag()); - } - }else{ - return true; - } - } - - return false; + return $this->id === $item->getId() and + (!$checkDamage or $this->getDamage() === $item->getDamage()) and + (!$checkCompound or $this->getNamedTag()->equals($item->getNamedTag())); } /** From 0ac5e03ce954ff8dd88cc05eef9d36e7e00dcb04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 20:59:43 +0000 Subject: [PATCH 58/59] Require PHPStan 0.12.9 minimum --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 89694fca9..9b21acce3 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "adhocore/json-comment": "^0.1.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.8", + "phpstan/phpstan": "^0.12.9", "irstea/phpunit-shim": "^8.5", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2" diff --git a/composer.lock b/composer.lock index 6b9ed7cdd..41e2834c3 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": "3bc1131c6ecd44aef9d1043f49563a6a", + "content-hash": "e22866a7924c444da73ff31b831b30cb", "packages": [ { "name": "adhocore/json-comment", From ada8cbb5451c260f5776d7f144420673858eeae3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Feb 2020 21:01:05 +0000 Subject: [PATCH 59/59] phpstan: drop some ignoreErrors that don't occur on 0.12.9 --- tests/phpstan/configs/phpstan-bugs.neon | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index bdbce964d..998fde5ad 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -5,14 +5,6 @@ parameters: message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" path: ../../../src - - - message: "#^Cannot access an offset on Threaded\\.$#" - path: ../../../src - - - - message: "#^Cannot assign new offset to Threaded\\.$#" - path: ../../../src - - message: "#^Offset string does not exist on array\\(\\)\\.$#" count: 3