Merge branch 'stable' into next-minor

This commit is contained in:
SOFe 2019-11-21 23:21:16 +08:00
commit cb76f8a5df
No known key found for this signature in database
GPG Key ID: 0C2A8814637DCBDE
22 changed files with 287 additions and 85 deletions

View File

@ -9,7 +9,7 @@ before_script:
- echo | pecl install channel://pecl.php.net/yaml-2.0.4
- git clone https://github.com/pmmp/pthreads.git
- cd pthreads
- git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0
- git checkout 1b7da492b944146fa9680f6399bd9c6c6c6095e0
- phpize
- ./configure
- make

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 1b3fe3120cac93ef8d821a1c62a3722576fcfd81
Subproject commit 185d7419914005530298bd5e069449bdf4c0be56

View File

@ -99,4 +99,9 @@ Plugin developers should **only** update their required API to this version if y
- `pocketmine\level\Explosion`:
- `explodeA()`
- `explodeB()`
- Fixed various cosmetic documentation inconsistencies in the core and dependencies.
- Fixed various cosmetic documentation inconsistencies in the core and dependencies.
# 3.9.7
- Fixed a crash that could occur during timezone detection.
- Squid no longer spin around constantly in enclosed spaces. Their performance impact is reduced.
- Cleaned up the bootstrap file.

View File

@ -36,7 +36,11 @@
"autoload": {
"psr-4": {
"": ["src"]
}
},
"files": [
"src/pocketmine/GlobalConstants.php",
"src/pocketmine/VersionInfo.php"
]
},
"autoload-dev": {
"psr-4": {

124
phpstan.neon Normal file
View File

@ -0,0 +1,124 @@
parameters:
level: 1
autoload_files:
- tests/phpstan/bootstrap.php
- src/pocketmine/PocketMine.php
paths:
- src
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
ignoreErrors:
-
message: "#^pocketmine\\\\Player\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\entity\\\\Human\\.$#"
path: src/pocketmine/Player.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: "#^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: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#"
count: 1
path: src/pocketmine/level/generator/hell/Nether.php
-
message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\normal\\\\Normal has an unused parameter \\$options\\.$#"
count: 1
path: src/pocketmine/level/generator/normal/Normal.php
-
message: "#^Used constant pocketmine\\\\RESOURCE_PATH not found\\.$#"
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
-
message: "#^Constant pocketmine\\\\DATA not found\\.$#"
path: src/pocketmine
-
message: "#^Constant pocketmine\\\\GIT_COMMIT not found\\.$#"
path: src/pocketmine
-
message: "#^Constant pocketmine\\\\PATH not found\\.$#"
path: src/pocketmine
-
message: "#^Constant pocketmine\\\\PLUGIN_PATH not found\\.$#"
path: src/pocketmine
-
message: "#^Constant pocketmine\\\\RESOURCE_PATH not found\\.$#"
path: src/pocketmine
-
message: "#^Constant pocketmine\\\\START_TIME not found\\.$#"
path: src/pocketmine
-
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

View File

@ -333,7 +333,7 @@ class CrashDump{
$this->data["general"]["php_os"] = PHP_OS;
$this->data["general"]["os"] = Utils::getOS();
$this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]");
$this->addLine("Git commit: " . GIT_COMMIT);
$this->addLine("Git commit: " . \pocketmine\GIT_COMMIT);
$this->addLine("uname -a: " . php_uname("a"));
$this->addLine("PHP Version: " . phpversion());
$this->addLine("Zend version: " . zend_version());

View File

@ -0,0 +1,30 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
// composer autoload doesn't use require_once and also pthreads can inherit things
if(defined('pocketmine\_GLOBAL_CONSTANTS_INCLUDED')){
return;
}
define('pocketmine\_GLOBAL_CONSTANTS_INCLUDED', true);
const INT32_MIN = -0x80000000;
const INT32_MAX = 0x7fffffff;
define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);

View File

@ -21,11 +21,6 @@
declare(strict_types=1);
namespace {
const INT32_MIN = -0x80000000;
const INT32_MAX = 0x7fffffff;
}
namespace pocketmine {
use pocketmine\utils\Internet;
@ -59,18 +54,18 @@ namespace pocketmine {
if(version_compare(MIN_PHP_VERSION, PHP_VERSION) > 0){
//If PHP version isn't high enough, anything below might break, so don't bother checking it.
return [
\pocketmine\NAME . " requires PHP >= " . MIN_PHP_VERSION . ", but you have PHP " . PHP_VERSION . "."
"PHP >= " . MIN_PHP_VERSION . " is required, but you have PHP " . PHP_VERSION . "."
];
}
$messages = [];
if(PHP_INT_SIZE < 8){
$messages[] = "Running " . \pocketmine\NAME . " with 32-bit systems/PHP is no longer supported. Please upgrade to a 64-bit system, or use a 64-bit PHP binary if this is a 64-bit system.";
$messages[] = "32-bit systems/PHP are no longer supported. Please upgrade to a 64-bit system, or use a 64-bit PHP binary if this is a 64-bit system.";
}
if(php_sapi_name() !== "cli"){
$messages[] = "You must run " . \pocketmine\NAME . " using the CLI.";
$messages[] = "Only PHP CLI is supported.";
}
$extensions = [
@ -123,6 +118,29 @@ namespace pocketmine {
return $messages;
}
function emit_performance_warnings(\Logger $logger){
if(extension_loaded("xdebug")){
$logger->warning("Xdebug extension is enabled. This has a major impact on performance.");
}
if(!extension_loaded("pocketmine_chunkutils")){
$logger->warning("ChunkUtils extension is missing. Anvil-format worlds will experience degraded performance.");
}
if(((int) ini_get('zend.assertions')) !== -1){
$logger->warning("Debugging assertions are enabled. This may degrade performance. To disable them, set `zend.assertions = -1` in php.ini.");
}
if(\Phar::running(true) === ""){
$logger->warning("Non-packaged installation detected. This will degrade autoloading speed and make startup times longer.");
}
}
function set_ini_entries(){
ini_set("allow_url_fopen", '1');
ini_set("display_errors", '1');
ini_set("display_startup_errors", '1');
ini_set("default_charset", "utf-8");
ini_set('assert.exception', '1');
}
function server(){
if(!empty($messages = check_platform_dependencies())){
echo PHP_EOL;
@ -138,6 +156,7 @@ namespace pocketmine {
unset($messages);
error_reporting(-1);
set_ini_entries();
if(\Phar::running(true) !== ""){
define('pocketmine\PATH', \Phar::running(true) . "/");
@ -163,20 +182,27 @@ namespace pocketmine {
set_error_handler([Utils::class, 'errorExceptionHandler']);
/*
* We now use the Composer autoloader, but this autoloader is still for loading plugins.
*/
$autoloader = new \BaseClassLoader();
$autoloader->register(false);
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
define('pocketmine\VERSION', $version->getFullVersion(true));
set_time_limit(0); //Who set it to 30 seconds?!?!
$gitHash = str_repeat("00", 20);
ini_set("allow_url_fopen", '1');
ini_set("display_errors", '1');
ini_set("display_startup_errors", '1');
ini_set("default_charset", "utf-8");
if(\Phar::running(true) === ""){
if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){
$gitHash = trim($out);
if(Process::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified
$gitHash .= "-dirty";
}
}
}else{
$phar = new \Phar(\Phar::running(false));
$meta = $phar->getMetadata();
if(isset($meta["git"])){
$gitHash = $meta["git"];
}
}
ini_set("memory_limit", '-1');
define('pocketmine\GIT_COMMIT', $gitHash);
define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'src' . DIRECTORY_SEPARATOR . 'pocketmine' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR);
@ -189,8 +215,7 @@ namespace pocketmine {
mkdir(\pocketmine\DATA, 0777, true);
}
define('pocketmine\LOCK_FILE_PATH', \pocketmine\DATA . 'server.lock');
define('pocketmine\LOCK_FILE', fopen(\pocketmine\LOCK_FILE_PATH, "a+b"));
define('pocketmine\LOCK_FILE', fopen(\pocketmine\DATA . 'server.lock', "a+b"));
if(!flock(\pocketmine\LOCK_FILE, LOCK_EX | LOCK_NB)){
//wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the
//other server wrote its PID and released exclusive lock before we get our lock
@ -224,42 +249,7 @@ namespace pocketmine {
}
unset($tzError);
if(extension_loaded("xdebug")){
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
}
if(!extension_loaded("pocketmine_chunkutils")){
$logger->warning("ChunkUtils extension is missing. Anvil-format worlds will experience degraded performance.");
}
if(\Phar::running(true) === ""){
$logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance.");
}
$version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER);
define('pocketmine\VERSION', $version->getFullVersion(true));
$gitHash = str_repeat("00", 20);
if(\Phar::running(true) === ""){
if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){
$gitHash = trim($out);
if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified
$gitHash .= "-dirty";
}
}
}else{
$phar = new \Phar(\Phar::running(false));
$meta = $phar->getMetadata();
if(isset($meta["git"])){
$gitHash = $meta["git"];
}
}
define('pocketmine\GIT_COMMIT', $gitHash);
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
emit_performance_warnings($logger);
$exitCode = 0;
do{
@ -274,6 +264,13 @@ 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.
*/
$autoloader = new \BaseClassLoader();
$autoloader->register(false);
new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
$logger->info("Stopping other threads");
@ -283,9 +280,7 @@ namespace pocketmine {
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
if(ThreadManager::getInstance()->stopAll() > 0){
if(\pocketmine\DEBUG > 1){
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
}
$logger->debug("Some threads could not be stopped, performing a force-kill");
Process::kill(getmypid());
}
}while(false);
@ -298,5 +293,7 @@ namespace pocketmine {
exit($exitCode);
}
\pocketmine\server();
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
\pocketmine\server();
}
}

View File

@ -1566,12 +1566,6 @@ class Server{
return;
}
if(((int) ini_get('zend.assertions')) !== -1){
$this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini.");
}
ini_set('assert.exception', '1');
if($this->logger instanceof MainLogger){
$this->logger->setLogDebug(\pocketmine\DEBUG > 1);
}

View File

@ -21,7 +21,15 @@
namespace pocketmine;
// composer autoload doesn't use require_once and also pthreads can inherit things
// TODO: drop this file and use a final class with constants
if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
return;
}
const _VERSION_INFO_INCLUDED = true;
const NAME = "PocketMine-MP";
const BASE_VERSION = "3.9.7";
const BASE_VERSION = "3.9.8";
const IS_DEVELOPMENT_BUILD = true;
const BUILD_NUMBER = 0;

View File

@ -141,6 +141,7 @@ class CommandReader extends Thread{
case self::TYPE_STREAM:
//stream_select doesn't work on piped streams for some reason
$r = [self::$stdin];
$w = $e = null;
if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds
return true;
}elseif($count === false){ //stream error

View File

@ -82,7 +82,7 @@ class Squid extends WaterAnimal{
return false;
}
if(++$this->switchDirectionTicker === 100 or $this->isCollided){
if(++$this->switchDirectionTicker === 100){
$this->switchDirectionTicker = 0;
if(mt_rand(0, 100) < 50){
$this->swimDirection = null;

View File

@ -90,6 +90,9 @@ class Painting extends Entity{
}
public function kill() : void{
if(!$this->isAlive()){
return;
}
parent::kill();
$drops = true;

View File

@ -378,7 +378,7 @@ class NetworkBinaryStream extends BinaryStream{
}
/**
* Writes an EntityUniqueID
* Writes an EntityRuntimeID
*
* @param int $eid
*/

View File

@ -29,6 +29,7 @@ use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\CommandData;
use pocketmine\network\mcpe\protocol\types\CommandEnum;
use pocketmine\network\mcpe\protocol\types\CommandParameter;
use pocketmine\utils\BinaryDataException;
use function count;
use function dechex;

View File

@ -143,7 +143,7 @@ abstract class DataPacket extends NetworkBinaryStream{
public function __debugInfo(){
$data = [];
foreach($this as $k => $v){
foreach((array) $this as $k => $v){
if($k === "buffer" and is_string($v)){
$data[$k] = bin2hex($v);
}elseif(is_string($v) or (is_object($v) and method_exists($v, "__toString"))){

View File

@ -40,8 +40,8 @@ final class RuntimeBlockMapping{
private static $legacyToRuntimeMap = [];
/** @var int[] */
private static $runtimeToLegacyMap = [];
/** @var mixed[] */
private static $bedrockKnownStates;
/** @var mixed[]|null */
private static $bedrockKnownStates = null;
private function __construct(){
//NOOP
@ -77,6 +77,12 @@ final class RuntimeBlockMapping{
}
}
private static function lazyInit() : void{
if(self::$bedrockKnownStates === null){
self::init();
}
}
/**
* Randomizes the order of the runtimeID table to prevent plugins relying on them.
* Plugins shouldn't use this stuff anyway, but plugin devs have an irritating habit of ignoring what they
@ -101,6 +107,7 @@ final class RuntimeBlockMapping{
* @return int
*/
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
self::lazyInit();
/*
* try id+meta first
* if not found, try id+0 (strip meta)
@ -115,6 +122,7 @@ final class RuntimeBlockMapping{
* @return int[] [id, meta]
*/
public static function fromStaticRuntimeId(int $runtimeId) : array{
self::lazyInit();
$v = self::$runtimeToLegacyMap[$runtimeId];
return [$v >> 4, $v & 0xf];
}
@ -128,7 +136,7 @@ final class RuntimeBlockMapping{
* @return array
*/
public static function getBedrockKnownStates() : array{
self::lazyInit();
return self::$bedrockKnownStates;
}
}
RuntimeBlockMapping::init();

View File

@ -0,0 +1,24 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
define('pocketmine\_PHPSTAN_ANALYSIS', true);

@ -1 +1 @@
Subproject commit 3fadb2c3f45a528a715733ba41c273289ef8ffb1
Subproject commit 73c96dfdbac9c9d44f3b10192540d7ff71a1051b

View File

@ -21,9 +21,11 @@ if [ $? -ne 0 ]; then
exit 1
fi
#Run PHPUnit tests
#7.5.12 introduces changes that set the build on fire because we don't ship libxml - TODO FIX
curl https://phar.phpunit.de/phpunit-7.5.11.phar --silent --location -o phpunit.phar
[ ! -f phpstan.phar ] && echo "Downloading PHPStan..." && curl -sSLO https://github.com/phpstan/phpstan/releases/download/0.11.19/phpstan.phar
"$PHP_BINARY" phpstan.phar analyze --no-progress --memory-limit=2G || exit 1
echo "PHPStan scan succeeded"
[ ! -f phpunit.phar ] && echo "Downloading PHPUnit..." && curl https://phar.phpunit.de/phpunit-7.phar --silent --location -o phpunit.phar
"$PHP_BINARY" phpunit.phar --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit || exit 1
#Run-the-server tests