Merge remote-tracking branch 'upstream/stable' into stable

This commit is contained in:
Stephen 2019-12-01 21:55:50 -05:00
commit e38c0c0fe1
30 changed files with 178 additions and 120 deletions

View File

@ -25,6 +25,7 @@
## Donate
- Bitcoin Cash (BCH): `qq3r46hn6ljnhnqnfwxt5pg3g447eq9jhvw5ddfear`
- Bitcoin (BTC): `171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV`
- Stellar Lumens (XLM): `GAAC5WZ33HCTE3BFJFZJXONMEIBNHFLBXM2HJVAZHXXPYA3HP5XPPS7T`
- [Patreon](https://www.patreon.com/pocketminemp)
## Licensing information

View File

@ -76,6 +76,6 @@ 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 10 seconds\n";
sleep(10);
echo "pushing changes in 5 seconds\n";
sleep(5);
system('git push origin HEAD ' . $currentVer->getBaseVersion());

@ -1 +1 @@
Subproject commit 8666ae5add7a8b5213d68b491ebf0de211998cc9
Subproject commit 185d7419914005530298bd5e069449bdf4c0be56

28
composer.lock generated
View File

@ -160,16 +160,16 @@
},
{
"name": "pocketmine/nbt",
"version": "0.2.11",
"version": "0.2.12",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "78784b93632c51f0fad0719b2d6ffe072529db6d"
"reference": "b5777265329753b74dd40bb105eedabeefb98724"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/78784b93632c51f0fad0719b2d6ffe072529db6d",
"reference": "78784b93632c51f0fad0719b2d6ffe072529db6d",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/b5777265329753b74dd40bb105eedabeefb98724",
"reference": "b5777265329753b74dd40bb105eedabeefb98724",
"shasum": ""
},
"require": {
@ -194,10 +194,10 @@
],
"description": "PHP library for working with Named Binary Tags",
"support": {
"source": "https://github.com/pmmp/NBT/tree/0.2.11",
"source": "https://github.com/pmmp/NBT/tree/0.2",
"issues": "https://github.com/pmmp/NBT/issues"
},
"time": "2019-10-21T14:50:43+00:00"
"time": "2019-12-01T08:20:26+00:00"
},
{
"name": "pocketmine/raklib",
@ -276,23 +276,20 @@
},
{
"name": "pocketmine/spl",
"version": "0.3.2",
"version": "0.3.3",
"source": {
"type": "git",
"url": "https://github.com/pmmp/SPL.git",
"reference": "7fd53857cd000491ba69e8db865792a024dd2c49"
"reference": "94d4df142fe837ba836e9348dd00209e4bdcc307"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/7fd53857cd000491ba69e8db865792a024dd2c49",
"reference": "7fd53857cd000491ba69e8db865792a024dd2c49",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/94d4df142fe837ba836e9348dd00209e4bdcc307",
"reference": "94d4df142fe837ba836e9348dd00209e4bdcc307",
"shasum": ""
},
"type": "library",
"autoload": {
"exclude-from-classmap": [
"stubs"
],
"classmap": [
"./"
]
@ -302,9 +299,10 @@
],
"description": "Standard library files required by PocketMine-MP and related projects",
"support": {
"source": "https://github.com/pmmp/SPL/tree/master"
"source": "https://github.com/pmmp/SPL/tree/0.3.3",
"issues": "https://github.com/pmmp/SPL/issues"
},
"time": "2018-08-12T15:17:39+00:00"
"time": "2019-10-28T11:41:20+00:00"
}
],
"packages-dev": [],

View File

@ -1,7 +1,11 @@
includes:
- tests/phpstan/configs/optional-com-dotnet.neon
- tests/phpstan/configs/optional-leveldb.neon
- tests/phpstan/configs/phpstan-bugs.neon
- tests/phpstan/configs/pthreads-bugs.neon
parameters:
level: 1
level: 2
autoload_files:
- tests/phpstan/bootstrap.php
- src/pocketmine/PocketMine.php
@ -57,22 +61,11 @@ parameters:
count: 1
path: src/pocketmine/network/mcpe/protocol/StartGamePacket.php
-
message: "#^Instantiated class COM not found\\.$#"
count: 2
path: src/pocketmine/network/upnp/UPnP.php
comment: "only available on Windows"
-
message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#"
count: 1
path: src/pocketmine/scheduler/TaskScheduler.php
-
message: "#^Variable \\$GLOBALS in isset\\(\\) always exists and is not nullable\\.$#"
path: src/pocketmine/MemoryManager.php
comment: "this isn't defined on threads (thanks pthreads)"
-
message: "#^Constant pocketmine\\\\COMPOSER_AUTOLOADER_PATH not found\\.$#"
path: src/pocketmine
@ -104,21 +97,9 @@ parameters:
-
message: "#^Constant pocketmine\\\\VERSION not found\\.$#"
path: src/pocketmine
-
message: "#^Used constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
comment: "explicitly checked"
-
message: "#^Constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
comment: "explicitly checked"
-
message: "#^Instantiated class LevelDB not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
comment: "leveldb extension currently optional"
-
message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:createDB\\(\\) has invalid type LevelDB\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:getDatabase\\(\\) has invalid type LevelDB\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#"
count: 1
path: src/pocketmine/command/defaults/TeleportCommand.php
comment: "not actually possible, but high cost to fix warning"

View File

@ -228,7 +228,7 @@ class Server{
* @var int
*/
private $tickCounter = 0;
/** @var int */
/** @var float */
private $nextTick = 0;
/** @var float[] */
private $tickAverage = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20];
@ -1445,7 +1445,7 @@ class Server{
}
/**
* @return string[]
* @return string[][]
*/
public function getCommandAliases() : array{
$section = $this->getProperty("aliases");
@ -1790,7 +1790,7 @@ class Server{
/**
* @param TextContainer|string $message
* @param Player[] $recipients
* @param CommandSender[] $recipients
*
* @return int
*/
@ -1799,7 +1799,7 @@ class Server{
return $this->broadcast($message, self::BROADCAST_CHANNEL_USERS);
}
/** @var Player[] $recipients */
/** @var CommandSender[] $recipients */
foreach($recipients as $recipient){
$recipient->sendMessage($message);
}

View File

@ -763,7 +763,7 @@ class Block extends Position implements BlockIds, Metadatable{
return $this->level->getBlockMetadata()->getMetadata($this, $metadataKey);
}
return null;
return [];
}
public function hasMetadata(string $metadataKey) : bool{

View File

@ -80,6 +80,9 @@ class BurningFurnace extends Solid{
$furnace = $this->getLevel()->getTile($this);
if(!($furnace instanceof TileFurnace)){
$furnace = Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this));
if(!($furnace instanceof TileFurnace)){
return true;
}
}
if(!$furnace->canOpenWith($item->getCustomName())){

View File

@ -109,6 +109,9 @@ class Chest extends Transparent{
$chest = $t;
}else{
$chest = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this));
if(!($chest instanceof TileChest)){
return true;
}
}
if(

View File

@ -47,6 +47,9 @@ class ItemFrame extends Flowable{
$tile = $this->level->getTile($this);
if(!($tile instanceof TileItemFrame)){
$tile = Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this));
if(!($tile instanceof TileItemFrame)){
return true;
}
}
if($tile->hasItem()){

View File

@ -55,7 +55,7 @@ abstract class Command{
*/
private $activeAliases = [];
/** @var CommandMap */
/** @var CommandMap|null */
private $commandMap = null;
/** @var string */

View File

@ -60,7 +60,6 @@ class GamemodeCommand extends VanillaCommand{
return true;
}
$target = $sender;
if(isset($args[1])){
$target = $sender->getServer()->getPlayer($args[1]);
if($target === null){
@ -68,7 +67,9 @@ class GamemodeCommand extends VanillaCommand{
return true;
}
}elseif(!($sender instanceof Player)){
}elseif($sender instanceof Player){
$target = $sender;
}else{
throw new InvalidCommandSyntaxException();
}

View File

@ -318,7 +318,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK
public static $entityCount = 1;
/** @var Entity[] */
/** @var string[] */
private static $knownEntities = [];
/** @var string[][] */
private static $saveNames = [];
@ -460,8 +460,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** @var EntityDamageEvent|null */
protected $lastDamageCause = null;
/** @var Block[] */
protected $blocksAround = [];
/** @var Block[]|null */
protected $blocksAround = null;
/** @var float|null */
public $lastX = null;

View File

@ -40,7 +40,7 @@ class Squid extends WaterAnimal{
public $width = 0.95;
public $height = 0.95;
/** @var Vector3 */
/** @var Vector3|null */
public $swimDirection = null;
public $swimSpeed = 0.1;

View File

@ -23,10 +23,12 @@ declare(strict_types=1);
namespace pocketmine\event\player;
use pocketmine\command\CommandSender;
use pocketmine\event\Cancellable;
use pocketmine\permission\PermissionManager;
use pocketmine\Player;
use pocketmine\Server;
use function spl_object_id;
/**
* Called when a player chats something
@ -39,15 +41,15 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
protected $format;
/**
* @var Player[]
* @var CommandSender[]
*/
protected $recipients = [];
/**
* @param Player $player
* @param string $message
* @param string $format
* @param Player[] $recipients
* @param Player $player
* @param string $message
* @param string $format
* @param CommandSender[] $recipients
*/
public function __construct(Player $player, string $message, string $format = "chat.type.text", array $recipients = null){
$this->player = $player;
@ -56,7 +58,11 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
$this->format = $format;
if($recipients === null){
$this->recipients = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_USERS);
foreach(PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_USERS) as $permissible){
if($permissible instanceof CommandSender){
$this->recipients[spl_object_id($permissible)] = $permissible;
}
}
}else{
$this->recipients = $recipients;
}
@ -100,14 +106,14 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
}
/**
* @return Player[]
* @return CommandSender[]
*/
public function getRecipients() : array{
return $this->recipients;
}
/**
* @param Player[] $recipients
* @param CommandSender[] $recipients
*/
public function setRecipients(array $recipients) : void{
$this->recipients = $recipients;

View File

@ -39,15 +39,15 @@ class PlayerCreationEvent extends Event{
/** @var int */
private $port;
/** @var Player::class */
/** @var string */
private $baseClass;
/** @var Player::class */
/** @var string */
private $playerClass;
/**
* @param SourceInterface $interface
* @param Player::class $baseClass
* @param Player::class $playerClass
* @param string $baseClass
* @param string $playerClass
* @param string $address
* @param int $port
*/
@ -91,14 +91,14 @@ class PlayerCreationEvent extends Event{
}
/**
* @return Player::class
* @return string
*/
public function getBaseClass(){
return $this->baseClass;
}
/**
* @param Player::class $class
* @param string $class
*/
public function setBaseClass($class){
if(!is_a($class, $this->baseClass, true)){
@ -109,14 +109,14 @@ class PlayerCreationEvent extends Event{
}
/**
* @return Player::class
* @return string
*/
public function getPlayerClass(){
return $this->playerClass;
}
/**
* @param Player::class $class
* @param string $class
*/
public function setPlayerClass($class){
if(!is_a($class, $this->baseClass, true)){

View File

@ -47,7 +47,7 @@ abstract class BaseInventory implements Inventory{
/** @var string */
protected $title;
/** @var \SplFixedArray|Item[] */
protected $slots = [];
protected $slots;
/** @var Player[] */
protected $viewers = [];
/** @var InventoryEventProcessor */

View File

@ -43,7 +43,7 @@ class CraftingManager{
/** @var FurnaceRecipe[] */
protected $furnaceRecipes = [];
/** @var BatchPacket */
/** @var BatchPacket|null */
private $craftingDataCache;
public function __construct(){

View File

@ -94,7 +94,7 @@ class Enchantment{
public const SLOT_ELYTRA = 0x4000;
public const SLOT_TRIDENT = 0x8000;
/** @var Enchantment[] */
/** @var \SplFixedArray|Enchantment[] */
protected static $enchantments;
public static function init() : void{

View File

@ -265,7 +265,7 @@ class Level implements ChunkManager, Metadatable{
/** @var LevelTimings */
public $timings;
/** @var int */
/** @var float */
public $tickRateTime = 0;
/**
* @deprecated

View File

@ -694,50 +694,48 @@ class Chunk{
public function initChunk(Level $level){
if(!$this->isInit){
$changed = false;
if($this->NBTentities !== null){
$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;
}
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);
$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;
}
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;
}
}
$level->timings->syncChunkLoadEntitiesTimer->stopTiming();
$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(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){
$changed = true;
continue;
}
}
}
$level->timings->syncChunkLoadTileEntitiesTimer->stopTiming();
$this->NBTentities = null;
$this->NBTtiles = null;
}
$this->NBTentities = [];
$level->timings->syncChunkLoadEntitiesTimer->stopTiming();
$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(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){
$changed = true;
continue;
}
}
}
$this->NBTtiles = [];
$level->timings->syncChunkLoadTileEntitiesTimer->stopTiming();
$this->hasChanged = $changed;

View File

@ -157,7 +157,11 @@ class NetworkBinaryStream extends BinaryStream{
if($c !== 1){
throw new \UnexpectedValueException("Unexpected NBT count $c");
}
$nbt = (new NetworkLittleEndianNBTStream())->read($this->buffer, false, $this->offset, 512);
$decodedNBT = (new NetworkLittleEndianNBTStream())->read($this->buffer, false, $this->offset, 512);
if(!($decodedNBT instanceof CompoundTag)){
throw new \UnexpectedValueException("Unexpected root tag type for itemstack");
}
$nbt = $decodedNBT;
}elseif($nbtLen !== 0){
throw new \UnexpectedValueException("Unexpected fake NBT length $nbtLen");
}

View File

@ -227,6 +227,7 @@ class AvailableCommandsPacket extends DataPacket{
$retval->aliases = $enums[$this->getLInt()] ?? null;
for($overloadIndex = 0, $overloadCount = $this->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){
$retval->overloads[$overloadIndex] = [];
for($paramIndex = 0, $paramCount = $this->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){
$parameter = new CommandParameter();
$parameter->paramName = $this->getString();

View File

@ -140,7 +140,7 @@ class CraftingDataPacket extends DataPacket{
}
$this->decodedEntries[] = $entry;
}
$this->getBool(); //cleanRecipes
$this->cleanRecipes = $this->getBool();
}
private static function writeEntry($entry, NetworkBinaryStream $stream, int $pos){

View File

@ -135,7 +135,7 @@ abstract class DataPacket extends NetworkBinaryStream{
abstract public function handle(NetworkSession $session) : bool;
public function clean(){
$this->buffer = null;
$this->buffer = "";
$this->isEncoded = false;
$this->offset = 0;
return $this;

View File

@ -263,6 +263,7 @@ class AsyncPool{
while(($task = $worker->unstack()) !== null){
//cancelRun() is not strictly necessary here, but it might be used to inform plugins of the task state
//(i.e. it never executed).
assert($task instanceof AsyncTask);
$task->cancelRun();
$this->removeTask($task, true);
}

View File

@ -0,0 +1,12 @@
parameters:
ignoreErrors:
-
message: "#^Instantiated class COM not found\\.$#"
count: 2
path: src/pocketmine/network/upnp/UPnP.php
-
message: "#^Access to property \\$StaticPortMappingCollection on an unknown class COM\\.$#"
count: 4
path: src/pocketmine/network/upnp/UPnP.php

View File

@ -0,0 +1,30 @@
parameters:
ignoreErrors:
-
message: "#^Used constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Instantiated class LevelDB not found\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:createDB\\(\\) has invalid type LevelDB\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:getDatabase\\(\\) has invalid type LevelDB\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Property pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:\\$db has unknown class LevelDB as its type\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php
-
message: "#^Call to method (get|put|delete|close)\\(\\) on an unknown class LevelDB\\.$#"
path: src/pocketmine/level/format/io/leveldb/LevelDB.php

View File

@ -0,0 +1,10 @@
parameters:
ignoreErrors:
-
message: "#^PHPDoc tag @param has invalid value \\(.+\\)\\: Unexpected token \"&\", expected TOKEN_VARIABLE at offset \\d+$#"
path: src/pocketmine
-
message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#"
path: src/pocketmine

View File

@ -0,0 +1,6 @@
parameters:
ignoreErrors:
-
message: "#^Variable \\$GLOBALS in isset\\(\\) always exists and is not nullable\\.$#"
path: src/pocketmine/MemoryManager.php