Compare commits

..

58 Commits

Author SHA1 Message Date
b296ae1b87 Release 3.17.3 2021-01-25 17:15:31 +00:00
f9e42b716a Scrub PHPStan baselines
these are now always generated with level 8.
2021-01-24 20:31:22 +00:00
34c1d455a7 phpstan: enable checkMissingCallableSignature 2021-01-24 20:27:53 +00:00
af8936dba5 phpstan 0.12.69 2021-01-24 20:14:42 +00:00
e8ffab1787 RegionLoader: avoid hitting the disk twice during chunk reads
this provides some performance improvement (although it's difficult to measure because of cache).
this does mean that we read some garbage data during chunk reads, but it's less costly than hitting the disk twice.
2021-01-20 21:05:44 +00:00
ecc1e1f698 RegionLoader: improve performance of region header validation
I was unaware that fseek actually makes a syscall which is rather costly, which became painfully obvious during large world conversions on PM4.
On average this problem appeared to be adding about 5ms to the load time for a newly loaded region, which is insanely expensive.
2021-01-20 20:04:21 +00:00
ea5931e274 Updated build/php submodule to pmmp/php-build-scripts@60194e8b14 2021-01-16 19:34:06 +00:00
988cf7f535 Fixed PHP 8.0 deprecation error 2021-01-16 19:31:07 +00:00
e156fb47e8 Disable xdebug on Actions 2021-01-15 21:09:45 +00:00
efc5f34877 wrong place ... when shared defaults :( 2021-01-15 17:53:39 +00:00
dd0d8842d5 actions: disable fail-fast 2021-01-15 17:35:27 +00:00
7bdc564ccc Update first-party dependencies to PHP 8.0 compatible versions
all deps of PM3 are ready (at least as far as PHPStan can show).
2021-01-15 16:59:51 +00:00
69fff23f1a LevelProviderManager: removed bogus @var
I'm not sure why this wasn't detected until 0.12.67...
2021-01-15 16:53:49 +00:00
ae43698e88 phpstan 0.12.67
for some reason dependabot shit itself while trying to scan for updates and thought this wasn't updatable ...
2021-01-15 16:53:49 +00:00
0987e03c03 Bump phpstan/phpstan-strict-rules from 0.12.8 to 0.12.9 (#4003) 2021-01-13 10:55:54 +00:00
97c124edf9 thanks git, this just sneaked in without any questions ................ 2021-01-12 21:43:34 +00:00
56501178b7 Updated composer dependencies 2021-01-12 21:41:25 +00:00
da663deea1 Bump phpstan/phpstan from 0.12.65 to 0.12.66 (#4001) 2021-01-12 10:41:59 +00:00
972c911485 phpstan 0.12.65 2021-01-09 18:04:42 +00:00
0d8858f948 composer.json: sort packages automatically 2021-01-09 17:38:22 +00:00
da71540fce first shot building multi PHP versions on actions 2021-01-05 22:03:51 +00:00
ec9b39862b bootstrap: commit suicide if composer dependencies are not in sync 2020-12-29 17:47:32 +00:00
efca8077d5 3.17.3 is next 2020-12-28 23:03:37 +00:00
5066d5225b Release 3.17.2 2020-12-28 23:03:32 +00:00
aefaf73685 Living: extract an applyConsumptionResults() method from consumeObject()
inspired by #3592, which has gone stale
2020-12-28 22:27:29 +00:00
15401d740f RegionLoader: mark area as garbage in removeChunk() 2020-12-27 19:16:05 +00:00
5920b0ba40 Remove _PHPSTAN_ANALYSIS constant
we don't need this anymore since PHPStan is able to intelligently decide whether to autoload a file or not.
2020-12-27 19:10:40 +00:00
dea75a0687 RegionLoader: do not attempt to auto-repair chunks with oversized lengths
In the old days, we used to try to correct this problem by adjusting the region header to match the
length found at the start of the chunk payload. However, this has a very good chance to cause corruption
of other chunks, since we can't do any fast overlap checks (an upsize might cause the chunk's alloocated
area to overlap into another one, causing corruption when either chunk's space gets written to).

This corruption risk has become more problematic since the
introduction of region garbage sector reuse, since a broken location
header could cause chunks to trash each others' saved data.

In addition, if there is a length mismatch, there's a good chance that the oversized chunk itself will
already be corrupted, so we'd just fail trying to decompress it later on.

So, instead of trying to fix this automatically, we bail and hope this doesn't occur often enough for
users to get upset, and allow external offline tools to attempt to repair the mess instead.
2020-12-27 18:50:52 +00:00
873e8740e0 3.17.2 is next 2020-12-23 22:20:24 +00:00
260c55f23a Release 3.17.1 2020-12-23 22:20:19 +00:00
9ed430acb9 CrashDump: fixed a bug in crashdump generation 2020-12-23 21:53:12 +00:00
f0241043de CrashDump: add server uptime to crash information 2020-12-23 20:26:18 +00:00
135f1c95e4 phpstan 0.12.64 2020-12-23 20:04:40 +00:00
5431807e43 Split tests up into multiple jobs
this gives a more granular view of test failures and also allows independent steps to run in parallel.
2020-12-23 19:48:39 +00:00
d49ae832e8 actions: rename cache miss fallback build step 2020-12-21 21:32:27 +00:00
ff9d013005 build: hash composer cache by lockfile instead of composer.json
this ensures a cache refresh when transitive dependencies are updated.
2020-12-20 23:58:37 +00:00
b0e1317818 Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-12-20 23:53:26 +00:00
8653afb0fb Updated composer dependencies 2020-12-20 23:53:09 +00:00
995b56aaa0 Fixed Composer package cache 2020-12-20 23:49:28 +00:00
3ecddf312d build.sh: sort configure parameters 2020-12-20 22:49:39 +00:00
470243ca6f experimental: build PHP in a separate build job 2020-12-20 22:30:47 +00:00
3f21e59917 Bump phpstan/phpstan-strict-rules from 0.12.5 to 0.12.7 (#3976) 2020-12-18 13:44:19 +00:00
fdd74a4f46 Bump phpstan/phpstan-phpunit from 0.12.16 to 0.12.17 (#3975) 2020-12-18 13:15:05 +00:00
a43b46a93c Merge branch 'stable' of https://github.com/pmmp/pocketmine-mp into stable 2020-12-18 00:33:10 +00:00
0604dfc9e5 phpstan 0.12.63 2020-12-18 00:32:55 +00:00
dd2c3db285 Fixed a bucket of lava disappearing when used in a furnace (#3973)
fixes #2385
2020-12-17 23:57:34 +00:00
c95e283507 fix CXXFLAGS 2020-12-14 22:02:16 +00:00
6afbd1f55c Squashed commit of the following:
commit 1f42169f0f929958f7d68a68f194c6f3492b7eb4
Author: Dylan K. Taylor <odigiman@gmail.com>
Date:   Mon Dec 14 21:23:44 2020 +0000

    ... install it in the right fucking place

commit d2a88abeda5fa937d3f508c4e0300a949af97846
Author: Dylan K. Taylor <odigiman@gmail.com>
Date:   Mon Dec 14 21:14:21 2020 +0000

    Build PHP using system libraries to reduce rebuild time
2020-12-14 21:58:58 +00:00
0682c93f5a Drop bcmath dependency
we haven't used bcmath since the days of 32-bit.
2020-12-14 20:59:07 +00:00
da90ae85da Updated composer dependencies 2020-12-14 19:24:36 +00:00
e87127f309 readme: drop travis badge in favour of GH Actions badge 2020-12-11 22:38:14 +00:00
0237a50d90 thank you for your service travis 2020-12-11 22:26:53 +00:00
8b53e4150e Setup GitHub Actions (#3966) 2020-12-11 22:25:08 +00:00
1c43538238 Fix that a hoe gets damage applied to it, when it's used to break a block (#3967)
closes #3965
2020-12-11 21:14:52 +00:00
68887105b2 Utils::cleanPath(): drop the square braces
this looks ugly, as well as breaking plugin crash detection (which tbh is too fragile, but it is what it is ...)
2020-12-09 20:26:08 +00:00
104e90b794 CrashDump: more robust core crash detection 2020-12-08 23:27:03 +00:00
994062f6dc CrashDump: fixed plugin detection on eval()'d code
it's possible we could clean the path up to detect which plugin caused the crash, but for now I'll be happy to not have them showing up as core crashes ...
2020-12-08 23:11:29 +00:00
69a41a5ed4 3.17.1 is next 2020-12-08 21:02:14 +00:00
43 changed files with 610 additions and 514 deletions

166
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,166 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
build-php:
name: Prepare PHP
runs-on: ubuntu-latest
strategy:
matrix:
php: [7.3.25, 7.4.13]
steps:
- uses: actions/checkout@v2 #needed for build.sh
- name: Check for PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Compile PHP
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: ./tests/gh-actions/build.sh "${{ matrix.php }}"
phpstan:
name: PHPStan analysis
needs: build-php
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [7.3.25, 7.4.13]
steps:
- uses: actions/checkout@v2
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --prefer-dist --no-interaction
- name: Run PHPStan
run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G
phpunit:
name: PHPUnit tests
needs: build-php
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [7.3.25, 7.4.13]
steps:
- uses: actions/checkout@v2
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --prefer-dist --no-interaction
- name: Run PHPUnit tests
run: ./vendor/bin/phpunit --bootstrap vendor/autoload.php --fail-on-warning tests/phpunit
integration:
name: Integration tests
needs: build-php
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [7.3.25, 7.4.13]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Restore PHP build cache
id: php-build-cache
uses: actions/cache@v2
with:
path: "./bin"
key: "php-build-generic-${{ matrix.php }}-${{ hashFiles('./tests/gh-actions/build.sh') }}"
- name: Kill build on PHP build cache miss (should never happen)
if: steps.php-build-cache.outputs.cache-hit != 'true'
run: exit 1
- name: Prefix PHP to PATH
run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php
- name: Restore Composer package cache
uses: actions/cache@v2
with:
path: |
~/.cache/composer/files
~/.cache/composer/vcs
key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}"
restore-keys: |
composer-v2-cache-
- name: Install Composer dependencies
run: php composer.phar install --no-dev --prefer-dist --no-interaction
- name: Run integration tests
run: ./tests/travis.sh -t4

View File

@ -1,21 +0,0 @@
import:
source: ./tests/travis/setup-php.yml
script:
- 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 --prefer-dist
- ./tests/travis.sh -t4
cache:
directories:
- $HOME/.composer/cache/files
- $HOME/.composer/cache/vcs
notifications:
email:
recipients:
- team@pmmp.io
on_success: change
on_failure: always

View File

@ -3,7 +3,7 @@
<b>A highly customisable, open source server software for Minecraft: Bedrock Edition written in PHP</b>
</p>
[![Build Status](https://travis-ci.com/pmmp/PocketMine-MP.svg?branch=master)](https://travis-ci.com/pmmp/PocketMine-MP)
![CI](https://github.com/pmmp/PocketMine-MP/workflows/CI/badge.svg)
## Getting started
- [Documentation](http://pmmp.readthedocs.org/)

View File

@ -24,7 +24,6 @@ declare(strict_types=1);
namespace pocketmine\build\make_release;
use pocketmine\utils\VersionString;
use function defined;
use function dirname;
use function fgets;
use function file_get_contents;
@ -86,6 +85,4 @@ function main(array $argv) : void{
system('git push origin HEAD ' . $currentVer->getBaseVersion());
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
main($argv);
}
main($argv);

View File

@ -26,7 +26,6 @@ namespace pocketmine\build\server_phar;
use pocketmine\utils\Git;
use function array_map;
use function count;
use function defined;
use function dirname;
use function file_exists;
use function getcwd;
@ -174,6 +173,4 @@ STUB
}
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
main();
}
main();

View File

@ -15,3 +15,20 @@ Plugin developers should **only** update their required API to this version if y
- Pumpkin and melon stems may not connect to their corresponding pumpkin/melon
- New blocks, items & mobs aren't implemented
- Nether doesn't exist
# 3.17.1
- Fixed some instances of plugin-caused crashes not being detected (eval()'d code, custom plugin paths).
- Server uptime is now included in crash reports.
- Hoes now take damage when used to break sponges.
- Using lava as fuel in a furnace now leaves behind an empty bucket.
# 3.17.2
- Fixed region header corruption when chunks with larger-than-expected lengths are found. These chunks are now treated as corrupted, instead of automatically attempting to salvage them (which usually fails anyway).
- `RegionLoader->removeChunk()` now allows the space used by the removed chunk to be reused by future region saves.
- Extracted `Living->applyConsumptionResults()` from `Living->consumeObject()` (preparation for a future bug fix).
# 3.17.3
- Improved performance of chunk loading in Region-based worlds.
- Improved performance of region header validation in Region-based worlds (indirect improvement to chunk loading performance).
- Fixed some PHP 8.0 language-level compatibility issues.
- Source installations will now exit with an error when Composer dependencies are not in sync with the current Git revision. Now, it's required to run `composer install` after every git pull to make sure the correct dependency versions are installed.

View File

@ -7,7 +7,6 @@
"require": {
"php": ">=7.3.0",
"php-64bit": "*",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-ctype": "*",
"ext-date": "*",
@ -38,7 +37,7 @@
"composer-runtime-api": "^2.0"
},
"require-dev": {
"phpstan/phpstan": "0.12.59",
"phpstan/phpstan": "0.12.69",
"phpstan/phpstan-phpunit": "^0.12.6",
"phpstan/phpstan-strict-rules": "^0.12.2",
"phpunit/phpunit": "^9.2"
@ -61,7 +60,8 @@
"config": {
"platform": {
"php": "7.3.0"
}
},
"sort-packages": true
},
"scripts": {
"make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/DevTools/ConsoleScript.php --make tests/plugins/DevTools --out plugins/DevTools.phar",

284
composer.lock generated
View File

@ -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": "2c44138f2052c259a201871d4d423947",
"content-hash": "5466cbf8934081309e4c8ad5c2781f65",
"packages": [
{
"name": "adhocore/json-comment",
@ -56,25 +56,25 @@
},
{
"name": "pocketmine/binaryutils",
"version": "0.1.12",
"version": "0.1.13",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BinaryUtils.git",
"reference": "566fa87829e007eda0bd96e39fe20b9b0d638132"
"reference": "0abee38d4e2861621f262c79a2a3d699d8a697f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/566fa87829e007eda0bd96e39fe20b9b0d638132",
"reference": "566fa87829e007eda0bd96e39fe20b9b0d638132",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/0abee38d4e2861621f262c79a2a3d699d8a697f4",
"reference": "0abee38d4e2861621f262c79a2a3d699d8a697f4",
"shasum": ""
},
"require": {
"php": ">=7.2",
"php": "^7.2 || ^8.0",
"php-64bit": "*"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.40",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
@ -90,34 +90,34 @@
"description": "Classes and methods for conveniently handling binary data",
"support": {
"issues": "https://github.com/pmmp/BinaryUtils/issues",
"source": "https://github.com/pmmp/BinaryUtils/tree/stable"
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.13"
},
"time": "2020-08-28T20:43:21+00:00"
"time": "2021-01-15T14:19:13+00:00"
},
{
"name": "pocketmine/callback-validator",
"version": "1.0.2",
"version": "1.0.3",
"source": {
"type": "git",
"url": "git@github.com:pmmp/CallbackValidator.git",
"reference": "8321aa3ccfe63639b0d08f0cbf270755cfc99fe2"
"url": "https://github.com/pmmp/CallbackValidator.git",
"reference": "64787469766bcaa7e5885242e85c23c25e8c55a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/CallbackValidator/zipball/8321aa3ccfe63639b0d08f0cbf270755cfc99fe2",
"reference": "8321aa3ccfe63639b0d08f0cbf270755cfc99fe2",
"url": "https://api.github.com/repos/pmmp/CallbackValidator/zipball/64787469766bcaa7e5885242e85c23c25e8c55a2",
"reference": "64787469766bcaa7e5885242e85c23c25e8c55a2",
"shasum": ""
},
"require": {
"ext-reflection": "*",
"php": ">=7.1"
"php": "^7.1 || ^8.0"
},
"replace": {
"daverandom/callback-validator": "*"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.38",
"phpstan/phpstan": "0.12.59",
"phpstan/phpstan-strict-rules": "^0.12.4",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.0"
},
@ -138,33 +138,37 @@
}
],
"description": "Fork of daverandom/callback-validator - Tools for validating callback signatures",
"time": "2020-08-21T19:51:42+00:00"
"support": {
"issues": "https://github.com/pmmp/CallbackValidator/issues",
"source": "https://github.com/pmmp/CallbackValidator/tree/1.0.3"
},
"time": "2020-12-11T01:45:37+00:00"
},
{
"name": "pocketmine/classloader",
"version": "0.1.1",
"version": "0.1.2",
"source": {
"type": "git",
"url": "https://github.com/pmmp/ClassLoader.git",
"reference": "7c0363491d1ce8f914fe96d41a4338c982adedff"
"reference": "9757928424652393b178a3760073113aa7c9911b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/7c0363491d1ce8f914fe96d41a4338c982adedff",
"reference": "7c0363491d1ce8f914fe96d41a4338c982adedff",
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/9757928424652393b178a3760073113aa7c9911b",
"reference": "9757928424652393b178a3760073113aa7c9911b",
"shasum": ""
},
"require": {
"ext-pthreads": "~3.2.0",
"ext-reflection": "*",
"php": ">=7.2.0"
"php": "^7.2 || ^8.0"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.38",
"phpstan/phpstan": "0.12.66",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
@ -180,32 +184,32 @@
"description": "Ad-hoc autoloading components used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/ClassLoader/issues",
"source": "https://github.com/pmmp/ClassLoader/tree/stable"
"source": "https://github.com/pmmp/ClassLoader/tree/0.1.2"
},
"time": "2020-08-22T11:48:51+00:00"
"time": "2021-01-15T00:40:47+00:00"
},
{
"name": "pocketmine/log",
"version": "0.2.0",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Log.git",
"reference": "e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa"
"reference": "830b44a2cf96ef703c550abe64302f230231ca49"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Log/zipball/e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa",
"reference": "e59bedb5d4bbeb9a26647cb7c367cb2fa72addfa",
"url": "https://api.github.com/repos/pmmp/Log/zipball/830b44a2cf96ef703c550abe64302f230231ca49",
"reference": "830b44a2cf96ef703c550abe64302f230231ca49",
"shasum": ""
},
"require": {
"php": ">=7.2"
"php": "^7.2 || ^8.0"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.2"
},
"type": "library",
@ -221,34 +225,36 @@
"description": "Logging components used by PocketMine-MP and related projects",
"support": {
"issues": "https://github.com/pmmp/Log/issues",
"source": "https://github.com/pmmp/Log/tree/0.2.0"
"source": "https://github.com/pmmp/Log/tree/0.2.1"
},
"time": "2020-03-31T15:43:47+00:00"
"time": "2021-01-15T14:32:41+00:00"
},
{
"name": "pocketmine/log-pthreads",
"version": "0.1.1",
"version": "0.1.3",
"source": {
"type": "git",
"url": "https://github.com/pmmp/LogPthreads.git",
"reference": "9bbcef398b01487ab47c234a6a7054722abbe067"
"reference": "e477ecf6ec214fdd4415ea1da3fdd9d73bf699ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/9bbcef398b01487ab47c234a6a7054722abbe067",
"reference": "9bbcef398b01487ab47c234a6a7054722abbe067",
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/e477ecf6ec214fdd4415ea1da3fdd9d73bf699ea",
"reference": "e477ecf6ec214fdd4415ea1da3fdd9d73bf699ea",
"shasum": ""
},
"require": {
"ext-pthreads": "~3.2.0",
"php": ">=7.2",
"php": "^7.2 || ^8.0",
"pocketmine/log": "^0.2.0"
},
"conflict": {
"pocketmine/spl": "<0.4"
},
"require-dev": {
"phpstan/phpstan": "^0.12.18"
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.66",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
"autoload": {
@ -263,31 +269,31 @@
"description": "Logging components specialized for pthreads used by PocketMine-MP and related projects",
"support": {
"issues": "https://github.com/pmmp/LogPthreads/issues",
"source": "https://github.com/pmmp/LogPthreads/tree/0.1.1"
"source": "https://github.com/pmmp/LogPthreads/tree/0.1.3"
},
"time": "2020-03-31T16:17:19+00:00"
"time": "2021-01-15T00:35:49+00:00"
},
{
"name": "pocketmine/math",
"version": "0.2.5",
"version": "0.2.6",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Math.git",
"reference": "8c46cfa95351fb0b2b30739a381310941934b55f"
"reference": "43057cb8c179a9859677b496a788db922fd5cfc3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Math/zipball/8c46cfa95351fb0b2b30739a381310941934b55f",
"reference": "8c46cfa95351fb0b2b30739a381310941934b55f",
"url": "https://api.github.com/repos/pmmp/Math/zipball/43057cb8c179a9859677b496a788db922fd5cfc3",
"reference": "43057cb8c179a9859677b496a788db922fd5cfc3",
"shasum": ""
},
"require": {
"php": ">=7.2.0",
"php": "^7.2 || ^8.0",
"php-64bit": "*"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.40",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
@ -303,34 +309,34 @@
"description": "PHP library containing math related code used in PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/Math/issues",
"source": "https://github.com/pmmp/Math/tree/stable"
"source": "https://github.com/pmmp/Math/tree/0.2.6"
},
"time": "2020-08-27T11:45:40+00:00"
"time": "2021-01-15T14:25:11+00:00"
},
{
"name": "pocketmine/nbt",
"version": "0.2.15",
"version": "0.2.16",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "f8a81d37d24eb79fb77d985a52549d68955bc6a1"
"reference": "be6d54a8a314967d938b501eee49d4641e2ab07d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/f8a81d37d24eb79fb77d985a52549d68955bc6a1",
"reference": "f8a81d37d24eb79fb77d985a52549d68955bc6a1",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/be6d54a8a314967d938b501eee49d4641e2ab07d",
"reference": "be6d54a8a314967d938b501eee49d4641e2ab07d",
"shasum": ""
},
"require": {
"ext-zlib": "*",
"php": ">=7.2.0",
"php": "^7.2 || ^8.0",
"php-64bit": "*",
"pocketmine/binaryutils": "^0.1.9"
},
"require-dev": {
"irstea/phpunit-shim": "^7.5 || ^8.0",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.40",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
@ -346,28 +352,28 @@
"description": "PHP library for working with Named Binary Tags",
"support": {
"issues": "https://github.com/pmmp/NBT/issues",
"source": "https://github.com/pmmp/NBT/tree/stable"
"source": "https://github.com/pmmp/NBT/tree/0.2.16"
},
"time": "2020-08-28T15:11:32+00:00"
"time": "2021-01-15T15:27:28+00:00"
},
{
"name": "pocketmine/raklib",
"version": "0.12.9",
"version": "0.12.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/RakLib.git",
"reference": "5f2a02009f486ca4d90892814570fa13ebdc078d"
"reference": "48e70551cca6f2409115d3468bed94c2edd08f31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/5f2a02009f486ca4d90892814570fa13ebdc078d",
"reference": "5f2a02009f486ca4d90892814570fa13ebdc078d",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/48e70551cca6f2409115d3468bed94c2edd08f31",
"reference": "48e70551cca6f2409115d3468bed94c2edd08f31",
"shasum": ""
},
"require": {
"ext-pthreads": "~3.2.0",
"ext-sockets": "*",
"php": ">=7.2.0",
"php": "^7.2 || ^8.0",
"php-64bit": "*",
"php-ipv6": "*",
"pocketmine/binaryutils": "^0.1.9",
@ -376,7 +382,7 @@
"pocketmine/snooze": "^0.1.0"
},
"require-dev": {
"phpstan/phpstan": "0.12.40",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.2"
},
"type": "library",
@ -392,31 +398,31 @@
"description": "A RakNet server implementation written in PHP",
"support": {
"issues": "https://github.com/pmmp/RakLib/issues",
"source": "https://github.com/pmmp/RakLib/tree/stable"
"source": "https://github.com/pmmp/RakLib/tree/0.12.10"
},
"time": "2020-08-28T15:22:57+00:00"
"time": "2021-01-15T16:19:15+00:00"
},
{
"name": "pocketmine/snooze",
"version": "0.1.3",
"version": "0.1.4",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Snooze.git",
"reference": "849510fa62e57512b8467e3694e9b3add97038fd"
"reference": "382ab149f01ecca0a57f999ff5d7fc9e271c3268"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/849510fa62e57512b8467e3694e9b3add97038fd",
"reference": "849510fa62e57512b8467e3694e9b3add97038fd",
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/382ab149f01ecca0a57f999ff5d7fc9e271c3268",
"reference": "382ab149f01ecca0a57f999ff5d7fc9e271c3268",
"shasum": ""
},
"require": {
"ext-pthreads": ">=3.1.7dev",
"php-64bit": ">=7.2.0"
"php-64bit": "^7.2 || ^8.0"
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "0.12.40",
"phpstan/phpstan": "0.12.67",
"phpstan/phpstan-strict-rules": "^0.12.4"
},
"type": "library",
@ -432,26 +438,26 @@
"description": "Thread notification management library for code using the pthreads extension",
"support": {
"issues": "https://github.com/pmmp/Snooze/issues",
"source": "https://github.com/pmmp/Snooze/tree/0.1.3"
"source": "https://github.com/pmmp/Snooze/tree/0.1.4"
},
"time": "2020-08-28T22:19:21+00:00"
"time": "2021-01-15T14:44:16+00:00"
},
{
"name": "pocketmine/spl",
"version": "0.4.1",
"version": "0.4.2",
"source": {
"type": "git",
"url": "https://github.com/pmmp/SPL.git",
"reference": "ff0579a0be41bbe65d3637607715c0f87728a838"
"reference": "6b08b7cf8c4afa17139c9a1b3bf1b408531de161"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/ff0579a0be41bbe65d3637607715c0f87728a838",
"reference": "ff0579a0be41bbe65d3637607715c0f87728a838",
"url": "https://api.github.com/repos/pmmp/SPL/zipball/6b08b7cf8c4afa17139c9a1b3bf1b408531de161",
"reference": "6b08b7cf8c4afa17139c9a1b3bf1b408531de161",
"shasum": ""
},
"require": {
"php": ">=7.2"
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.8"
@ -469,9 +475,9 @@
"description": "Standard library files required by PocketMine-MP and related projects",
"support": {
"issues": "https://github.com/pmmp/SPL/issues",
"source": "https://github.com/pmmp/SPL/tree/0.4.1"
"source": "https://github.com/pmmp/SPL/tree/0.4.2"
},
"time": "2020-01-31T16:18:03+00:00"
"time": "2021-01-15T15:15:23+00:00"
}
],
"packages-dev": [
@ -604,16 +610,16 @@
},
{
"name": "nikic/php-parser",
"version": "v4.10.3",
"version": "v4.10.4",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984"
"reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984",
"reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e",
"reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e",
"shasum": ""
},
"require": {
@ -654,9 +660,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.10.3"
"source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4"
},
"time": "2020-12-03T17:45:45+00:00"
"time": "2020-12-20T10:01:03+00:00"
},
{
"name": "phar-io/manifest",
@ -720,16 +726,16 @@
},
{
"name": "phar-io/version",
"version": "3.0.3",
"version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
"reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae"
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phar-io/version/zipball/726c026815142e4f8677b7cb7f2249c9ffb7ecae",
"reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae",
"url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451",
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451",
"shasum": ""
},
"require": {
@ -765,9 +771,9 @@
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
"source": "https://github.com/phar-io/version/tree/3.0.3"
"source": "https://github.com/phar-io/version/tree/3.0.4"
},
"time": "2020-11-30T09:21:21+00:00"
"time": "2020-12-13T23:18:30+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@ -929,16 +935,16 @@
},
{
"name": "phpspec/prophecy",
"version": "1.12.1",
"version": "1.12.2",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d"
"reference": "245710e971a030f42e08f4912863805570f23d39"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d",
"reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
"reference": "245710e971a030f42e08f4912863805570f23d39",
"shasum": ""
},
"require": {
@ -950,7 +956,7 @@
},
"require-dev": {
"phpspec/phpspec": "^6.0",
"phpunit/phpunit": "^8.0 || ^9.0 <9.3"
"phpunit/phpunit": "^8.0 || ^9.0"
},
"type": "library",
"extra": {
@ -990,22 +996,22 @@
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/1.12.1"
"source": "https://github.com/phpspec/prophecy/tree/1.12.2"
},
"time": "2020-09-29T09:10:42+00:00"
"time": "2020-12-19T10:15:11+00:00"
},
{
"name": "phpstan/phpstan",
"version": "0.12.59",
"version": "0.12.69",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "cf4107257c8ca2ad967efdd6a00f12b21acbb779"
"reference": "8f436ea35241da33487fd0d38b4bc3e6dfe30ea8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/cf4107257c8ca2ad967efdd6a00f12b21acbb779",
"reference": "cf4107257c8ca2ad967efdd6a00f12b21acbb779",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f436ea35241da33487fd0d38b4bc3e6dfe30ea8",
"reference": "8f436ea35241da33487fd0d38b4bc3e6dfe30ea8",
"shasum": ""
},
"require": {
@ -1036,7 +1042,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/0.12.59"
"source": "https://github.com/phpstan/phpstan/tree/0.12.69"
},
"funding": [
{
@ -1052,39 +1058,34 @@
"type": "tidelift"
}
],
"time": "2020-12-07T14:46:03+00:00"
"time": "2021-01-24T14:55:37+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
"version": "0.12.16",
"version": "0.12.17",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "1dd916d181b0539dea5cd37e91546afb8b107e17"
"reference": "432575b41cf2d4f44e460234acaf56119ed97d36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/1dd916d181b0539dea5cd37e91546afb8b107e17",
"reference": "1dd916d181b0539dea5cd37e91546afb8b107e17",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/432575b41cf2d4f44e460234acaf56119ed97d36",
"reference": "432575b41cf2d4f44e460234acaf56119ed97d36",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0",
"phpstan/phpstan": "^0.12.33"
"phpstan/phpstan": "^0.12.60"
},
"conflict": {
"phpunit/phpunit": "<7.0"
},
"require-dev": {
"consistence/coding-standard": "^3.5",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"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 || ^8.0 || ^9.0",
"satooshi/php-coveralls": "^1.0",
"slevomat/coding-standard": "^4.7.2"
"phing/phing": "^2.16.3",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-strict-rules": "^0.12.6",
"phpunit/phpunit": "^7.5.20"
},
"type": "phpstan-extension",
"extra": {
@ -1110,37 +1111,33 @@
"description": "PHPUnit extensions and rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
"source": "https://github.com/phpstan/phpstan-phpunit/tree/0.12.16"
"source": "https://github.com/phpstan/phpstan-phpunit/tree/0.12.17"
},
"time": "2020-08-05T13:28:50+00:00"
"time": "2020-12-13T12:12:51+00:00"
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "0.12.5",
"version": "0.12.9",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "334898a32217e4605e0f9cfa3d3fc3101bda26be"
"reference": "0705fefc7c9168529fd130e341428f5f10f4f01d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/334898a32217e4605e0f9cfa3d3fc3101bda26be",
"reference": "334898a32217e4605e0f9cfa3d3fc3101bda26be",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/0705fefc7c9168529fd130e341428f5f10f4f01d",
"reference": "0705fefc7c9168529fd130e341428f5f10f4f01d",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0",
"phpstan/phpstan": "^0.12.33"
"phpstan/phpstan": "^0.12.66"
},
"require-dev": {
"consistence/coding-standard": "^3.0.1",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"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"
"phing/phing": "^2.16.3",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-phpunit": "^0.12.16",
"phpunit/phpunit": "^7.5.20"
},
"type": "phpstan-extension",
"extra": {
@ -1165,9 +1162,9 @@
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/master"
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/0.12.9"
},
"time": "2020-08-30T15:42:06+00:00"
"time": "2021-01-13T08:50:28+00:00"
},
{
"name": "phpunit/php-code-coverage",
@ -2556,16 +2553,16 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.20.0",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41"
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41",
"reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
"shasum": ""
},
"require": {
@ -2577,7 +2574,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -2615,7 +2612,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0"
},
"funding": [
{
@ -2631,7 +2628,7 @@
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "theseer/tokenizer",
@ -2745,7 +2742,6 @@
"platform": {
"php": ">=7.3.0",
"php-64bit": "*",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-ctype": "*",
"ext-date": "*",

View File

@ -17,6 +17,7 @@ includes:
parameters:
level: 8
checkExplicitMixed: true
checkMissingCallableSignature: true
bootstrapFiles:
- tests/phpstan/bootstrap.php
scanDirectories:

View File

@ -28,6 +28,7 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo;
use pocketmine\plugin\PluginBase;
use pocketmine\plugin\PluginLoadOrder;
use pocketmine\plugin\PluginManager;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Utils;
use pocketmine\utils\VersionString;
use function base64_encode;
@ -46,6 +47,7 @@ use function is_resource;
use function json_encode;
use function json_last_error_msg;
use function max;
use function microtime;
use function mkdir;
use function ob_end_clean;
use function ob_get_contents;
@ -58,7 +60,6 @@ use function sprintf;
use function str_split;
use function strpos;
use function substr;
use function time;
use function zend_version;
use function zlib_encode;
use const E_COMPILE_ERROR;
@ -89,7 +90,7 @@ class CrashDump{
* having their content changed, version format changing, etc.
* It is not necessary to increase this when adding new fields.
*/
private const FORMAT_VERSION = 3;
private const FORMAT_VERSION = 4;
private const PLUGIN_INVOLVEMENT_NONE = "none";
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
@ -99,7 +100,7 @@ class CrashDump{
private $server;
/** @var resource */
private $fp;
/** @var int */
/** @var float */
private $time;
/**
* @var mixed[]
@ -112,12 +113,12 @@ class CrashDump{
private $path;
public function __construct(Server $server){
$this->time = time();
$this->time = microtime(true);
$this->server = $server;
if(!is_dir($this->server->getDataPath() . "crashdumps")){
mkdir($this->server->getDataPath() . "crashdumps");
}
$this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
$this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log";
$fp = @fopen($this->path, "wb");
if(!is_resource($fp)){
throw new \RuntimeException("Could not create Crash Dump");
@ -125,7 +126,8 @@ class CrashDump{
$this->fp = $fp;
$this->data["format_version"] = self::FORMAT_VERSION;
$this->data["time"] = $this->time;
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", $this->time));
$this->data["uptime"] = $this->time - \pocketmine\START_TIME;
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", (int) $this->time));
$this->addLine();
$this->baseCrash();
$this->generalData();
@ -166,7 +168,9 @@ class CrashDump{
if($json === false){
throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg());
}
$this->encodedData = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
$zlibEncoded = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9);
if($zlibEncoded === false) throw new AssumptionFailedError("ZLIB compression failed");
$this->encodedData = $zlibEncoded;
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
$this->addLine($line);
}
@ -310,8 +314,8 @@ class CrashDump{
}
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
if(strpos($frameCleanPath, "plugins") === 0 and file_exists($filePath)){
$frameCleanPath = Utils::cleanPath($filePath);
if(strpos($frameCleanPath, Utils::CLEAN_PATH_SRC_PREFIX) !== 0){
$this->addLine();
if($crashFrame){
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
@ -321,15 +325,17 @@ class CrashDump{
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT;
}
$reflection = new \ReflectionClass(PluginBase::class);
$file = $reflection->getProperty("file");
$file->setAccessible(true);
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$filePath = Utils::cleanPath($file->getValue($plugin));
if(strpos($frameCleanPath, $filePath) === 0){
$this->data["plugin"] = $plugin->getName();
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
break;
if(file_exists($filePath)){
$reflection = new \ReflectionClass(PluginBase::class);
$file = $reflection->getProperty("file");
$file->setAccessible(true);
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$filePath = Utils::cleanPath($file->getValue($plugin));
if(strpos($frameCleanPath, $filePath) === 0){
$this->data["plugin"] = $plugin->getName();
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
break;
}
}
}
return true;

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine {
use Composer\InstalledVersions;
use pocketmine\utils\Git;
use pocketmine\utils\MainLogger;
use pocketmine\utils\Process;
@ -73,7 +74,6 @@ namespace pocketmine {
}
$extensions = [
"bcmath" => "BC Math",
"curl" => "cURL",
"ctype" => "ctype",
"date" => "Date",
@ -206,6 +206,19 @@ namespace pocketmine {
define('pocketmine\GIT_COMMIT', $gitHash);
$composerGitHash = InstalledVersions::getReference('pocketmine/pocketmine-mp');
if($composerGitHash !== null){
$currentGitHash = explode("-", \pocketmine\GIT_COMMIT)[0];
if($currentGitHash !== $composerGitHash){
critical_error("Composer dependencies and/or autoloader are out of sync.");
critical_error("- Current revision is $currentGitHash");
critical_error("- Composer dependencies were last synchronized for revision $composerGitHash");
critical_error("Out-of-sync Composer dependencies may result in crashes and classes not being found.");
critical_error("Please synchronize Composer dependencies before running the server.");
exit(1);
}
}
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR);
@ -280,7 +293,7 @@ namespace pocketmine {
if(ThreadManager::getInstance()->stopAll() > 0){
$logger->debug("Some threads could not be stopped, performing a force-kill");
Process::kill(getmypid());
Process::kill(Process::pid());
}
}while(false);
@ -300,7 +313,5 @@ namespace pocketmine {
exit($exitCode);
}
if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){
\pocketmine\server();
}
\pocketmine\server();
}

View File

@ -126,7 +126,6 @@ use function file_put_contents;
use function filemtime;
use function function_exists;
use function get_class;
use function getmypid;
use function getopt;
use function gettype;
use function implode;
@ -1939,7 +1938,7 @@ class Server{
}catch(\Throwable $e){
$this->logger->logException($e);
$this->logger->emergency("Crashed while crashing, killing process");
@Process::kill(getmypid());
@Process::kill(Process::pid());
}
}
@ -2132,7 +2131,7 @@ class Server{
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
sleep($spacing);
}
@Process::kill(getmypid());
@Process::kill(Process::pid());
exit(1);
}

View File

@ -33,6 +33,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){
const _VERSION_INFO_INCLUDED = true;
const NAME = "PocketMine-MP";
const BASE_VERSION = "3.17.0";
const BASE_VERSION = "3.17.3";
const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0;

View File

@ -35,5 +35,6 @@ interface BlockToolType{
public const TYPE_PICKAXE = 1 << 2;
public const TYPE_AXE = 1 << 3;
public const TYPE_SHEARS = 1 << 4;
public const TYPE_HOE = 1 << 5;
}

View File

@ -31,6 +31,10 @@ class Sponge extends Solid{
$this->meta = $meta;
}
public function getToolType() : int{
return BlockToolType::TYPE_HOE;
}
public function getHardness() : float{
return 0.6;
}

View File

@ -300,17 +300,20 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($consumable instanceof MaybeConsumable and !$consumable->canBeConsumed()){
return false;
}
if($consumable instanceof FoodSource && $consumable->requiresHunger() and !$this->isHungry()){
return false;
}
return parent::consumeObject($consumable);
}
protected function applyConsumptionResults(Consumable $consumable) : void{
if($consumable instanceof FoodSource){
if($consumable->requiresHunger() and !$this->isHungry()){
return false;
}
$this->addFood($consumable->getFoodRestore());
$this->addSaturation($consumable->getSaturationRestore());
}
return parent::consumeObject($consumable);
parent::applyConsumptionResults($consumable);
}
/**

View File

@ -363,13 +363,20 @@ abstract class Living extends Entity implements Damageable{
return false;
}
$this->applyConsumptionResults($consumable);
return true;
}
/**
* Applies effects from consuming the object. This shouldn't do any can-consume checks (those are expected to be
* handled by the caller).
*/
protected function applyConsumptionResults(Consumable $consumable) : void{
foreach($consumable->getAdditionalEffects() as $effect){
$this->addEffect($effect);
}
$consumable->onConsume($this);
return true;
}
/**

View File

@ -50,6 +50,14 @@ class Bucket extends Item implements MaybeConsumable{
return 0;
}
public function getFuelResidue() : Item{
if($this->meta === Block::LAVA or $this->meta === Block::FLOWING_LAVA){
return ItemFactory::get(Item::BUCKET);
}
return parent::getFuelResidue();
}
public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{
$resultBlock = BlockFactory::get($this->meta);

View File

@ -23,11 +23,24 @@ declare(strict_types=1);
namespace pocketmine\item;
use pocketmine\block\Block;
use pocketmine\block\BlockToolType;
use pocketmine\entity\Entity;
class Hoe extends TieredTool{
public function getBlockToolType() : int{
return BlockToolType::TYPE_HOE;
}
public function onAttackEntity(Entity $victim) : bool{
return $this->applyDamage(1);
}
public function onDestroyBlock(Block $block) : bool{
if($block->getHardness() > 0){
return $this->applyDamage(1);
}
return false;
}
}

View File

@ -655,6 +655,16 @@ class Item implements ItemIds, \JsonSerializable{
return 0;
}
/**
* Returns an item after burning fuel
*/
public function getFuelResidue() : Item{
$item = clone $this;
$item->pop();
return $item;
}
/**
* Returns how many points of damage this item will deal to an entity when used as a weapon.
*/

View File

@ -921,7 +921,9 @@ class Chunk{
$biomeIds = $stream->get(256);
if($lightPopulated){
$heightMap = array_values(unpack("v*", $stream->get(512)));
/** @var int[] $unpackedHeightMap */
$unpackedHeightMap = unpack("v*", $stream->get(512)); //unpack() will never fail here
$heightMap = array_values($unpackedHeightMap);
}
}

View File

@ -63,7 +63,6 @@ abstract class LevelProviderManager{
throw new \InvalidArgumentException("Class $class cannot be constructed");
}
/** @var LevelProvider $class */
self::$providers[strtolower($class::getProviderName())] = $class;
}

View File

@ -368,7 +368,9 @@ class LevelDB extends BaseLevelProvider{
if(($maps2d = $this->db->get($index . self::TAG_DATA_2D)) !== false){
$binaryStream->setBuffer($maps2d, 0);
$heightMap = array_values(unpack("v*", $binaryStream->get(512)));
/** @var int[] $unpackedHeightMap */
$unpackedHeightMap = unpack("v*", $binaryStream->get(512)); //unpack() will never fail here
$heightMap = array_values($unpackedHeightMap);
$biomeIds = $binaryStream->get(256);
}
break;
@ -411,8 +413,13 @@ class LevelDB extends BaseLevelProvider{
$subChunks[$yy] = new SubChunk($ids, $data, $skyLight, $blockLight);
}
$heightMap = array_values(unpack("C*", $binaryStream->get(256)));
$biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024))));
/** @var int[] $unpackedHeightMap */
$unpackedHeightMap = unpack("C*", $binaryStream->get(256)); //unpack() will never fail here, but static analysers don't know that
$heightMap = array_values($unpackedHeightMap);
/** @var int[] $unpackedBiomeIds */
$unpackedBiomeIds = unpack("N*", $binaryStream->get(1024)); //nor here
$biomeIds = ChunkUtils::convertBiomeColors(array_values($unpackedBiomeIds));
break;
default:
//TODO: set chunks read-only so the version on disk doesn't get overwritten

View File

@ -182,7 +182,9 @@ class McRegion extends BaseLevelProvider{
$heightMap = [];
if($chunk->hasTag("HeightMap", ByteArrayTag::class)){
$heightMap = array_values(unpack("C*", $chunk->getByteArray("HeightMap")));
/** @var int[] $unpackedHeightMap */
$unpackedHeightMap = unpack("C*", $chunk->getByteArray("HeightMap")); //unpack() will never fail here
$heightMap = array_values($unpackedHeightMap);
}elseif($chunk->hasTag("HeightMap", IntArrayTag::class)){
$heightMap = $chunk->getIntArray("HeightMap"); #blameshoghicp
}

View File

@ -27,7 +27,8 @@ use pocketmine\level\format\ChunkException;
use pocketmine\level\format\io\exception\CorruptedChunkException;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Binary;
use pocketmine\utils\MainLogger;
use pocketmine\utils\BinaryDataException;
use pocketmine\utils\BinaryStream;
use function assert;
use function ceil;
use function chr;
@ -146,37 +147,34 @@ class RegionLoader{
fseek($this->filePointer, $this->locationTable[$index]->getFirstSector() << 12);
$prefix = fread($this->filePointer, 4);
if($prefix === false or strlen($prefix) !== 4){
throw new CorruptedChunkException("Corrupted chunk header detected (unexpected end of file reading length prefix)");
}
$length = Binary::readInt($prefix);
/*
* this might cause us to read some junk, but under normal circumstances it won't be any more than 4096 bytes wasted.
* doing this in a single call is faster than making two seeks and reads to fetch the chunk.
* this relies on the assumption that the end of the file is always padded to a multiple of 4096 bytes.
*/
$bytesToRead = $this->locationTable[$index]->getSectorCount() << 12;
$payload = fread($this->filePointer, $bytesToRead);
if($length <= 0){ //TODO: if we reached here, the locationTable probably needs updating
return null;
}
if($length > self::MAX_SECTOR_LENGTH){ //corrupted
throw new CorruptedChunkException("Length for chunk x=$x,z=$z ($length) is larger than maximum " . self::MAX_SECTOR_LENGTH);
if($payload === false || strlen($payload) !== $bytesToRead){
throw new CorruptedChunkException("Corrupted chunk detected (unexpected EOF, truncated or non-padded chunk found)");
}
$stream = new BinaryStream($payload);
if($length > ($this->locationTable[$index]->getSectorCount() << 12)){ //Invalid chunk, bigger than defined number of sectors
MainLogger::getLogger()->error("Chunk x=$x,z=$z length mismatch (expected " . ($this->locationTable[$index]->getSectorCount() << 12) . " sectors, got $length sectors)");
$old = $this->locationTable[$index];
$this->locationTable[$index] = new RegionLocationTableEntry($old->getFirstSector(), $length >> 12, time());
$this->writeLocationIndex($index);
}
try{
$length = $stream->getInt();
if($length <= 0){ //TODO: if we reached here, the locationTable probably needs updating
return null;
}
$chunkData = fread($this->filePointer, $length);
if($chunkData === false or strlen($chunkData) !== $length){
throw new CorruptedChunkException("Corrupted chunk detected (unexpected end of file reading chunk data)");
}
$compression = $stream->getByte();
if($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){
throw new CorruptedChunkException("Invalid compression type (got $compression, expected " . self::COMPRESSION_ZLIB . " or " . self::COMPRESSION_GZIP . ")");
}
$compression = ord($chunkData[0]);
if($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){
throw new CorruptedChunkException("Invalid compression type (got $compression, expected " . self::COMPRESSION_ZLIB . " or " . self::COMPRESSION_GZIP . ")");
return $stream->get($length - 1); //length prefix includes the compression byte
}catch(BinaryDataException $e){
throw new CorruptedChunkException("Corrupted chunk detected: " . $e->getMessage(), 0, $e);
}
return substr($chunkData, 1);
}
/**
@ -186,6 +184,23 @@ class RegionLoader{
return $this->isChunkGenerated(self::getChunkOffset($x, $z));
}
private function disposeGarbageArea(RegionLocationTableEntry $oldLocation) : void{
/* release the area containing the old copy to the garbage pool */
$this->garbageTable->add($oldLocation);
$endGarbage = $this->garbageTable->end();
$nextSector = $this->nextSector;
for(; $endGarbage !== null and $endGarbage->getLastSector() + 1 === $nextSector; $endGarbage = $this->garbageTable->end()){
$nextSector = $endGarbage->getFirstSector();
$this->garbageTable->remove($endGarbage);
}
if($nextSector !== $this->nextSector){
$this->nextSector = $nextSector;
ftruncate($this->filePointer, $this->nextSector << 12);
}
}
/**
* @return void
* @throws ChunkException
@ -230,20 +245,7 @@ class RegionLoader{
$this->writeLocationIndex($index);
if($oldLocation !== null){
/* release the area containing the old copy to the garbage pool */
$this->garbageTable->add($oldLocation);
$endGarbage = $this->garbageTable->end();
$nextSector = $this->nextSector;
for(; $endGarbage !== null and $endGarbage->getLastSector() + 1 === $nextSector; $endGarbage = $this->garbageTable->end()){
$nextSector = $endGarbage->getFirstSector();
$this->garbageTable->remove($endGarbage);
}
if($nextSector !== $this->nextSector){
$this->nextSector = $nextSector;
ftruncate($this->filePointer, $this->nextSector << 12);
}
$this->disposeGarbageArea($oldLocation);
}
}
@ -253,8 +255,12 @@ class RegionLoader{
*/
public function removeChunk(int $x, int $z){
$index = self::getChunkOffset($x, $z);
$oldLocation = $this->locationTable[$index];
$this->locationTable[$index] = null;
$this->writeLocationIndex($index);
if($oldLocation !== null){
$this->disposeGarbageArea($oldLocation);
}
}
/**
@ -336,6 +342,8 @@ class RegionLoader{
/** @var int[] $usedOffsets */
$usedOffsets = [];
$fileSize = filesize($this->filePath);
if($fileSize === false) throw new AssumptionFailedError("filesize() should not return false here");
for($i = 0; $i < 1024; ++$i){
$entry = $this->locationTable[$i];
if($entry === null){
@ -348,8 +356,7 @@ class RegionLoader{
//TODO: more validity checks
fseek($this->filePointer, $fileOffset);
if(feof($this->filePointer)){
if($fileOffset >= $fileSize){
throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset");
}
if(isset($usedOffsets[$offset])){

View File

@ -29,7 +29,10 @@ namespace pocketmine\metadata;
use pocketmine\plugin\Plugin;
abstract class MetadataStore{
/** @var \SplObjectStorage[]|MetadataValue[][] */
/**
* @var \SplObjectStorage[]|MetadataValue[][]
* @phpstan-var array<string, \SplObjectStorage<Plugin, MetadataValue>>
*/
private $metadataMap;
/**
@ -41,6 +44,7 @@ abstract class MetadataStore{
$owningPlugin = $newMetadataValue->getOwningPlugin();
if(!isset($this->metadataMap[$key])){
/** @phpstan-var \SplObjectStorage<Plugin, MetadataValue> $entry */
$entry = new \SplObjectStorage();
$this->metadataMap[$key] = $entry;
}else{
@ -92,7 +96,6 @@ abstract class MetadataStore{
* @return void
*/
public function invalidateAll(Plugin $owningPlugin){
/** @var \SplObjectStorage|MetadataValue[] $values */
foreach($this->metadataMap as $values){
if(isset($values[$owningPlugin])){
$values[$owningPlugin]->invalidate();

View File

@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\utils\AssumptionFailedError;
use function assert;
use function get_class;
use function strlen;
@ -72,7 +73,9 @@ class BatchPacket extends DataPacket{
}
protected function encodePayload(){
$this->put(zlib_encode($this->payload, ZLIB_ENCODING_RAW, $this->compressionLevel));
$encoded = zlib_encode($this->payload, ZLIB_ENCODING_RAW, $this->compressionLevel);
if($encoded === false) throw new AssumptionFailedError("ZLIB compression failed");
$this->put($encoded);
}
/**

View File

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

View File

@ -701,9 +701,18 @@ class PluginManager{
}
$handlerClosure = $method->getClosure($listener);
if($handlerClosure === null) throw new AssumptionFailedError("This should never happen");
try{
$eventClass = $parameters[0]->getClass();
$paramType = $parameters[0]->getType();
//isBuiltin() returns false for builtin classes ..................
if($paramType instanceof \ReflectionNamedType && !$paramType->isBuiltin()){
/** @phpstan-var class-string $paramClass */
$paramClass = $paramType->getName();
$eventClass = new \ReflectionClass($paramClass);
}else{
$eventClass = null;
}
}catch(\ReflectionException $e){ //class doesn't exist
if(isset($tags["softDepend"]) && !isset($this->plugins[$tags["softDepend"]])){
$this->server->getLogger()->debug("Not registering @softDepend listener " . Utils::getNiceClosureName($handlerClosure) . "() because plugin \"" . $tags["softDepend"] . "\" not found");

View File

@ -51,6 +51,7 @@ use function unserialize;
abstract class AsyncTask extends Collectable{
/**
* @var \SplObjectStorage|null
* @phpstan-var \SplObjectStorage<AsyncTask, mixed>
* Used to store objects on the main thread which should not be serialized.
*/
private static $threadLocalStorage;
@ -258,7 +259,9 @@ abstract class AsyncTask extends Collectable{
}
if(self::$threadLocalStorage === null){
self::$threadLocalStorage = new \SplObjectStorage(); //lazy init
/** @phpstan-var \SplObjectStorage<AsyncTask, mixed> $storage */
$storage = new \SplObjectStorage();
self::$threadLocalStorage = $storage; //lazy init
}
if(isset(self::$threadLocalStorage[$this])){

View File

@ -152,8 +152,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
}
if($this->burnTime > 0 and $ev->isBurning()){
$fuel->pop();
$this->inventory->setFuel($fuel);
$this->inventory->setFuel($fuel->getFuelResidue());
}
}

View File

@ -30,6 +30,8 @@ use function fclose;
use function file;
use function file_get_contents;
use function function_exists;
use function getmypid;
use function getmyuid;
use function hexdec;
use function memory_get_usage;
use function posix_kill;
@ -175,4 +177,20 @@ final class Process{
return proc_close($process);
}
public static function pid() : int{
$result = getmypid();
if($result === false){
throw new \LogicException("getmypid() doesn't work on this platform");
}
return $result;
}
public static function uid() : int{
$result = getmyuid();
if($result === false){
throw new \LogicException("getmyuid() doesn't work on this platform");
}
return $result;
}
}

View File

@ -24,7 +24,6 @@ declare(strict_types=1);
namespace pocketmine\utils;
use pocketmine\Thread;
use function getmypid;
use function time;
class ServerKiller extends Thread{
@ -55,7 +54,7 @@ class ServerKiller extends Thread{
});
if(time() - $start >= $this->time){
echo "\nTook too long to stop, server was killed forcefully!\n";
@Process::kill(getmypid());
@Process::kill(Process::pid());
}
}

View File

@ -94,7 +94,7 @@ class UUID{
}
public static function fromRandom() : UUID{
return self::fromData(Binary::writeInt(time()), Binary::writeShort(getmypid()), Binary::writeShort(getmyuid()), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)));
return self::fromData(Binary::writeInt(time()), Binary::writeShort(($pid = getmypid()) !== false ? $pid : 0), Binary::writeShort(($uid = getmyuid()) !== false ? $uid : 0), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)));
}
public function toBinary() : string{

View File

@ -106,6 +106,9 @@ class Utils{
public const OS_BSD = "bsd";
public const OS_UNKNOWN = "other";
public const CLEAN_PATH_SRC_PREFIX = "pmsrc";
public const CLEAN_PATH_PLUGINS_PREFIX = "plugins";
/** @var string|null */
public static $os;
/** @var UUID|null */
@ -114,6 +117,8 @@ class Utils{
/**
* Generates an unique identifier to a callable
*
* @phpstan-param callable(mixed...) : mixed $variable
*
* @return string
*/
public static function getCallableIdentifier(callable $variable){
@ -129,6 +134,7 @@ class Utils{
/**
* Returns a readable identifier for the given Closure, including file and line.
*
* @phpstan-param \Closure(mixed...) : mixed $closure
* @throws \ReflectionException
*/
public static function getNiceClosureName(\Closure $closure) : string{
@ -189,7 +195,14 @@ class Utils{
}
$machine = php_uname("a");
$machine .= ($cpuinfo = @file("/proc/cpuinfo")) !== false ? implode(preg_grep("/(model name|Processor|Serial)/", $cpuinfo)) : "";
$cpuinfo = @file("/proc/cpuinfo");
if($cpuinfo !== false){
$cpuinfoLines = preg_grep("/(model name|Processor|Serial)/", $cpuinfo);
if($cpuinfoLines === false){
throw new AssumptionFailedError("Pattern is valid, so this shouldn't fail ...");
}
$machine .= implode("", $cpuinfoLines);
}
$machine .= sys_get_temp_dir();
$machine .= $extra;
$os = Utils::getOS();
@ -604,8 +617,8 @@ class Utils{
//remove relative paths
//TODO: make these paths dynamic so they can be unit-tested against
static $cleanPaths = [
\pocketmine\PLUGIN_PATH => "plugins", //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations
\pocketmine\PATH => ""
\pocketmine\PLUGIN_PATH => self::CLEAN_PATH_PLUGINS_PREFIX, //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations
\pocketmine\PATH => self::CLEAN_PATH_SRC_PREFIX
];
foreach($cleanPaths as $cleanPath => $replacement){
$cleanPath = rtrim(str_replace([DIRECTORY_SEPARATOR, "phar://"], ["/", ""], $cleanPath), "/");
@ -675,6 +688,8 @@ class Utils{
*
* @param callable $signature Dummy callable with the required parameters and return type
* @param callable $subject Callable to check the signature of
* @phpstan-param callable(mixed...) : mixed $signature
* @phpstan-param callable(mixed...) : mixed $subject
*
* @throws \DaveRandom\CallbackValidator\InvalidCallbackException
* @throws \TypeError

25
tests/gh-actions/build.sh Executable file
View File

@ -0,0 +1,25 @@
VERSION="$1"
sudo apt update && sudo apt install -y \
re2c \
libtool \
libtool-bin \
zlib1g-dev \
libcurl4-openssl-dev \
libxml2-dev \
libyaml-dev \
libgmp-dev \
libzip-dev \
libssl-dev
INSTALL_DIR="$(pwd)/bin/php7"
export CFLAGS="$CFLAGS -march=x86-64"
export CXXFLAGS="$CXXFLAGS -march=x86-64"
git clone https://github.com/php-build/php-build.git
cd php-build
./install-dependencies.sh
echo '"pthreads",,"https://github.com/pmmp/pthreads.git",,,"extension",' >> share/php-build/extension/definition
PHP_BUILD_INSTALL_EXTENSION='pthreads=@2bcd8b8c10395d58b8a9bc013e3a5328080c867f yaml=2.2.0' PHP_BUILD_ZTS_ENABLE=on ./bin/php-build "$VERSION" "$INSTALL_DIR"
rm "$INSTALL_DIR/etc/conf.d/xdebug.ini" || true

View File

@ -21,8 +21,6 @@
declare(strict_types=1);
define('pocketmine\_PHPSTAN_ANALYSIS', true);
if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){
//leveldb might not be loaded
define('LEVELDB_ZLIB_RAW_COMPRESSION', 4);

View File

@ -745,6 +745,11 @@ parameters:
count: 1
path: ../../../src/pocketmine/level/generator/normal/Normal.php
-
message: "#^Method pocketmine\\\\metadata\\\\MetadataStore\\:\\:getMetadataInternal\\(\\) should return array\\<pocketmine\\\\metadata\\\\MetadataValue\\> but returns SplObjectStorage\\<pocketmine\\\\plugin\\\\Plugin, pocketmine\\\\metadata\\\\MetadataValue\\>\\.$#"
count: 1
path: ../../../src/pocketmine/metadata/MetadataStore.php
-
message: "#^Variable method call on pocketmine\\\\event\\\\Listener\\.$#"
count: 1

View File

@ -45,6 +45,31 @@ parameters:
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#1 \\$str of function base64_decode expects string, mixed given\\.$#"
count: 5
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#1 \\$height of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage constructor expects int, mixed given\\.$#"
count: 2
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#2 \\$width of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage constructor expects int, mixed given\\.$#"
count: 2
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#8 \\$premium of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects bool, mixed given\\.$#"
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#9 \\$persona of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects bool, mixed given\\.$#"
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#10 \\$personaCapeOnClassic of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects bool, mixed given\\.$#"
count: 1
@ -65,31 +90,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#8 \\$premium of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects bool, mixed given\\.$#"
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#9 \\$persona of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects bool, mixed given\\.$#"
count: 1
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#1 \\$str of function base64_decode expects string, mixed given\\.$#"
count: 5
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#1 \\$height of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage constructor expects int, mixed given\\.$#"
count: 2
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#2 \\$width of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage constructor expects int, mixed given\\.$#"
count: 2
path: ../../../src/pocketmine/Player.php
-
message: "#^Parameter \\#1 \\.\\.\\.\\$slots of method pocketmine\\\\inventory\\\\BaseInventory\\:\\:addItem\\(\\) expects pocketmine\\\\item\\\\Item, mixed given\\.$#"
count: 1
@ -275,11 +275,6 @@ parameters:
count: 6
path: ../../../src/pocketmine/level/generator/noise/Noise.php
-
message: "#^Cannot call method invalidate\\(\\) on mixed\\.$#"
count: 1
path: ../../../src/pocketmine/metadata/MetadataStore.php
-
message: "#^Parameter \\#1 \\$buffer of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BatchPacket constructor expects string, mixed given\\.$#"
count: 1
@ -450,11 +445,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php
-
message: "#^Parameter \\#1 \\$table of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\StartGamePacket\\:\\:serializeItemTable\\(\\) expects array\\<string, int\\>, mixed given\\.$#"
count: 1
path: ../../../src/pocketmine/network/mcpe/protocol/StartGamePacket.php
-
message: "#^Parameter \\#1 \\$value of static method pocketmine\\\\permission\\\\Permission\\:\\:getByName\\(\\) expects bool\\|string, mixed given\\.$#"
count: 1

View File

@ -60,16 +60,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/PocketMine.php
-
message: "#^Parameter \\#1 \\$filename of function is_file expects string, array\\<int, mixed\\>\\|string given\\.$#"
count: 1
path: ../../../src/pocketmine/PocketMine.php
-
message: "#^Binary operation \"\\.\" between 'Composer autoloader…' and array\\<int, mixed\\>\\|string\\|false results in an error\\.$#"
count: 1
path: ../../../src/pocketmine/PocketMine.php
-
message: "#^Binary operation \"\\.\" between array\\<int, mixed\\>\\|string\\|false and '/'\\|'\\\\\\\\' results in an error\\.$#"
count: 2
@ -155,51 +145,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/block/Cactus.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Farmland.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Farmland.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Farmland.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#1 \\$min of function mt_rand expects int, float\\|int given\\.$#"
count: 3
@ -210,36 +155,6 @@ parameters:
count: 3
path: ../../../src/pocketmine/block/Grass.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Ice.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Ice.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Ice.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 23
path: ../../../src/pocketmine/block/Liquid.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 23
path: ../../../src/pocketmine/block/Liquid.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 23
path: ../../../src/pocketmine/block/Liquid.php
-
message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#"
count: 3
@ -295,36 +210,6 @@ parameters:
count: 2
path: ../../../src/pocketmine/block/Sapling.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Sapling.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Sapling.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/Sapling.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/SnowLayer.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/SnowLayer.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/block/SnowLayer.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 2
@ -400,21 +285,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/entity/Human.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/entity/Living.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/entity/Living.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/entity/Living.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
@ -435,21 +305,6 @@ parameters:
count: 3
path: ../../../src/pocketmine/entity/projectile/Projectile.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 2
path: ../../../src/pocketmine/entity/projectile/Projectile.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 2
path: ../../../src/pocketmine/entity/projectile/Projectile.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 2
path: ../../../src/pocketmine/entity/projectile/Projectile.php
-
message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\<T of object\\>\\|T of object, string given\\.$#"
count: 1
@ -685,11 +540,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/level/Level.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\format\\\\Chunk\\:\\:setBlock\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/level/Level.php
-
message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:chunkBlockHash\\(\\) expects int, float\\|int given\\.$#"
count: 1
@ -770,16 +620,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/level/generator/object/TallGrass.php
-
message: "#^Method pocketmine\\\\metadata\\\\MetadataStore\\:\\:getMetadataInternal\\(\\) should return array\\<pocketmine\\\\metadata\\\\MetadataValue\\> but returns array\\<pocketmine\\\\metadata\\\\MetadataValue\\>\\|SplObjectStorage\\.$#"
count: 1
path: ../../../src/pocketmine/metadata/MetadataStore.php
-
message: "#^Cannot call method count\\(\\) on array\\<pocketmine\\\\metadata\\\\MetadataValue\\>\\|SplObjectStorage\\.$#"
count: 1
path: ../../../src/pocketmine/metadata/MetadataStore.php
-
message: "#^Parameter \\#1 \\$str of method pocketmine\\\\utils\\\\BinaryStream\\:\\:put\\(\\) expects string, string\\|false given\\.$#"
count: 2
@ -985,18 +825,3 @@ parameters:
count: 3
path: ../../../src/pocketmine/tile/Tile.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/tile/Tile.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/tile/Tile.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/pocketmine/tile/Tile.php

View File

@ -1445,11 +1445,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/network/mcpe/convert/RuntimeBlockMapping.php
-
message: "#^Parameter \\#1 \\$that of method pocketmine\\\\nbt\\\\tag\\\\NamedTag\\:\\:equals\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\NamedTag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#"
count: 1
path: ../../../src/pocketmine/network/mcpe/convert/RuntimeBlockMapping.php
-
message: "#^Method pocketmine\\\\network\\\\mcpe\\\\convert\\\\RuntimeBlockMapping\\:\\:getBedrockKnownStates\\(\\) should return array\\<pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\> but returns array\\<pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\>\\|null\\.$#"
count: 1
@ -1485,11 +1480,6 @@ parameters:
count: 1
path: ../../../src/pocketmine/plugin/PluginBase.php
-
message: "#^Parameter \\#1 \\$closure of static method pocketmine\\\\utils\\\\Utils\\:\\:getNiceClosureName\\(\\) expects Closure, Closure\\|null given\\.$#"
count: 3
path: ../../../src/pocketmine/plugin/PluginManager.php
-
message: "#^Cannot call method handleException\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#"
count: 1

View File

@ -1,18 +0,0 @@
language: php
php:
- 7.3
- 7.4
before_script:
- phpenv config-rm xdebug.ini
- echo | pecl install channel://pecl.php.net/yaml-2.1.0
- git clone https://github.com/pmmp/pthreads.git
- cd pthreads
- git checkout b81ab29df58fa0fb239a9d5ca1c2380a0d087feb
- phpize
- ./configure
- make
- make install
- cd ..
- echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer self-update --2