Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor 2023-05-17 15:45:03 +01:00
commit ee9ce8a4f4
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
20 changed files with 150 additions and 204 deletions

View File

@ -13,7 +13,7 @@ jobs:
strategy: strategy:
matrix: matrix:
image: [ubuntu-20.04] image: [ubuntu-20.04]
php: [8.0.28, 8.1.18, 8.2.5] php: [8.1.19, 8.2.6]
steps: steps:
- name: Build and prepare PHP cache - name: Build and prepare PHP cache
@ -32,7 +32,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
image: [ubuntu-20.04] image: [ubuntu-20.04]
php: [8.0.28, 8.1.18, 8.2.5] php: [8.1.19, 8.2.6]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -71,7 +71,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
image: [ubuntu-20.04] image: [ubuntu-20.04]
php: [8.0.28, 8.1.18, 8.2.5] php: [8.1.19, 8.2.6]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -110,7 +110,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
image: [ubuntu-20.04] image: [ubuntu-20.04]
php: [8.0.28, 8.1.18, 8.2.5] php: [8.1.19, 8.2.6]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -151,7 +151,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
image: [ubuntu-20.04] image: [ubuntu-20.04]
php: [8.0.28, 8.1.18, 8.2.5] php: [8.1.19, 8.2.6]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@ -22,7 +22,6 @@
declare(strict_types=1); declare(strict_types=1);
const VERSIONS = [ const VERSIONS = [
"8.0",
"8.1", "8.1",
"8.2" "8.2"
]; ];

View File

@ -2,13 +2,13 @@
## Pre-requisites ## Pre-requisites
- A bash shell (git bash is sufficient for Windows) - A bash shell (git bash is sufficient for Windows)
- [`git`](https://git-scm.com) available in your shell - [`git`](https://git-scm.com) available in your shell
- PHP 8.0 or newer available in your shell - PHP 8.1 or newer available in your shell
- [`composer`](https://getcomposer.org) available in your shell - [`composer`](https://getcomposer.org) available in your shell
## Custom PHP binaries ## Custom PHP binaries
Because PocketMine-MP requires several non-standard PHP extensions and configuration, PMMP provides scripts to build custom binaries for running PocketMine-MP, as well as prebuilt binaries. Because PocketMine-MP requires several non-standard PHP extensions and configuration, PMMP provides scripts to build custom binaries for running PocketMine-MP, as well as prebuilt binaries.
- [Prebuilt binaries](https://jenkins.pmmp.io/job/PHP-8.0-Aggregate) - [Prebuilt binaries](https://github.com/pmmp/PHP-Binaries/releases)
- [Compile scripts](https://github.com/pmmp/php-build-scripts) are provided as a submodule in the path `build/php` - [Compile scripts](https://github.com/pmmp/php-build-scripts) are provided as a submodule in the path `build/php`
If you use a custom binary, you'll need to replace `composer` usages in this guide with `path/to/your/php path/to/your/composer.phar`. If you use a custom binary, you'll need to replace `composer` usages in this guide with `path/to/your/php path/to/your/composer.phar`.
@ -29,11 +29,5 @@ Run `composer make-server` using your preferred PHP binary. It'll drop a `Pocket
You can also use the `--out` option to change the output filename. You can also use the `--out` option to change the output filename.
There is a bug in PHP that might cause an error which looks like this:
```
Fatal error: Uncaught BadMethodCallException: unable to create temporary file in PocketMine-MP/build/server-phar.php:119
```
You can work around it by setting `ulimit -n` to some bigger number, e.g. `8192`, or by updating your PHP version to at least 8.0.3.
## Running PocketMine-MP from source code ## Running PocketMine-MP from source code
Run `src/PocketMine.php` using your preferred PHP binary. Run `src/PocketMine.php` using your preferred PHP binary.

View File

@ -18,6 +18,30 @@ Larger contributions like feature additions should be preceded by a [Change Prop
## Other things you'll need ## Other things you'll need
- [git](https://git-scm.com/) - [git](https://git-scm.com/)
## List of `pocketmine` namespaces which are in other repos
PocketMine-MP has several dependencies which are independent from the main server code. Most of them use the `pocketmine` namespace.
Some of these add extra classes to packages which already exist in PocketMine-MP.
Take a look at the table below if you can't find the class or function you're looking for.
| Source URL | Namespace, class or function |
|:----------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------|
| [pmmp/BedrockProtocol](https://github.com/pmmp/BedrockProtocol) | `pocketmine\network\mcpe\protocol` |
| [pmmp/BinaryUtils](https://github.com/pmmp/BinaryUtils) | `pocketmine\utils\BinaryDataException`</br>`pocketmine\utils\BinaryStream`</br>`pocketmine\utils\Binary` |
| [pmmp/ClassLoader](https://github.com/pmmp/`ClassLoader`) | `BaseClassLoader`</br>`ClassLoader`</br>`DynamicClassLoader` |
| [pmmp/Color](https://github.com/pmmp/Color) | `pocketmine\color` |
| [pmmp/ErrorHandler](https://github.com/pmmp/ErrorHandler) | `pocketmine\errorhandler` |
| [pmmp/LogPthreads](https://github.com/pmmp/LogPthreads) | `ThreadedLoggerAttachment`</br>`ThreadedLogger`</br>`AttachableThreadedLogger` |
| [pmmp/Log](https://github.com/pmmp/Log) | `AttachableLogger`</br>`BufferedLogger`</br>`GlobalLogger`</br>`LogLevel`</br>`Logger`</br>`PrefixedLogger`</br>`SimpleLogger` |
| [pmmp/Math](https://github.com/pmmp/Math) | `pocketmine\math` |
| [pmmp/NBT](https://github.com/pmmp/NBT) | `pocketmine\nbt` |
| [pmmp/RakLibIpc](https://github.com/pmmp/RakLibIpc) | `raklib\server\ipc` |
| [pmmp/RakLib](https://github.com/pmmp/RakLib) | `raklib` |
| [pmmp/Snooze](https://github.com/pmmp/Snooze) | `pocketmine\snooze` |
| [pmmp/ext-chunkutils2](https://github.com/pmmp/ext-chunkutils2) | `pocketmine\world\format\LightArray`</br>`pocketmine\world\format\PalettedBlockArray`</br>`pocketmine\world\format\io\SubChunkConverter` |
| [pmmp/ext-morton](https://github.com/pmmp/ext-morton) | `morton2d_decode`</br>`morton2d_encode`</br>`morton3d_decode`</br>`morton3d_encode` |
| [pmmp/ext-libdeflate](https://github.com/pmmp/ext-libdeflate) | `libdeflate_deflate_compress`</br>`libdeflate_gzip_compress`</br>`libdeflate_zlib_compress` |
## Choosing a target branch ## Choosing a target branch
PocketMine-MP has three primary branches of development. PocketMine-MP has three primary branches of development.

@ -1 +1 @@
Subproject commit a3c40579ad91246b07053fc2c8f085efd442943a Subproject commit f860ade30acc074a98bbf5ff286f35b5eda10c86

View File

@ -5,7 +5,7 @@
"homepage": "https://pmmp.io", "homepage": "https://pmmp.io",
"license": "LGPL-3.0", "license": "LGPL-3.0",
"require": { "require": {
"php": "^8.0", "php": "^8.1",
"php-64bit": "*", "php-64bit": "*",
"ext-chunkutils2": "^0.3.1", "ext-chunkutils2": "^0.3.1",
"ext-crypto": "^0.3.1", "ext-crypto": "^0.3.1",
@ -55,7 +55,7 @@
"symfony/filesystem": "^5.4" "symfony/filesystem": "^5.4"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "1.10.14", "phpstan/phpstan": "1.10.15",
"phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0", "phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "^9.2" "phpunit/phpunit": "^9.2"
@ -76,7 +76,7 @@
}, },
"config": { "config": {
"platform": { "platform": {
"php": "8.0.0" "php": "8.1.0"
}, },
"sort-packages": true "sort-packages": true
}, },

160
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "3bec710f35fbbdb9ce28481b84fbd312", "content-hash": "8c09886bd34e74a61c3ea1ee2be3b2e9",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -903,21 +903,20 @@
}, },
{ {
"name": "ramsey/collection", "name": "ramsey/collection",
"version": "1.3.0", "version": "2.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/ramsey/collection.git", "url": "https://github.com/ramsey/collection.git",
"reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
"reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.4 || ^8.0", "php": "^8.1"
"symfony/polyfill-php81": "^1.23"
}, },
"require-dev": { "require-dev": {
"captainhook/plugin-composer": "^5.3", "captainhook/plugin-composer": "^5.3",
@ -977,7 +976,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/ramsey/collection/issues", "issues": "https://github.com/ramsey/collection/issues",
"source": "https://github.com/ramsey/collection/tree/1.3.0" "source": "https://github.com/ramsey/collection/tree/2.0.0"
}, },
"funding": [ "funding": [
{ {
@ -989,7 +988,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-12-27T19:12:24+00:00" "time": "2022-12-31T21:50:55+00:00"
}, },
{ {
"name": "ramsey/uuid", "name": "ramsey/uuid",
@ -1394,114 +1393,35 @@
} }
], ],
"time": "2022-11-03T14:55:06+00:00" "time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a",
"reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php81\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "doctrine/instantiator", "name": "doctrine/instantiator",
"version": "1.5.0", "version": "2.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/instantiator.git", "url": "https://github.com/doctrine/instantiator.git",
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
"reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1 || ^8.0" "php": "^8.1"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^9 || ^11", "doctrine/coding-standard": "^11",
"ext-pdo": "*", "ext-pdo": "*",
"ext-phar": "*", "ext-phar": "*",
"phpbench/phpbench": "^0.16 || ^1", "phpbench/phpbench": "^1.2",
"phpstan/phpstan": "^1.4", "phpstan/phpstan": "^1.9.4",
"phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "phpunit/phpunit": "^9.5.27",
"vimeo/psalm": "^4.30 || ^5.4" "vimeo/psalm": "^5.4"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -1528,7 +1448,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/instantiator/issues", "issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.5.0" "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
}, },
"funding": [ "funding": [
{ {
@ -1544,7 +1464,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-12-30T00:15:36+00:00" "time": "2022-12-30T00:23:10+00:00"
}, },
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
@ -1774,16 +1694,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.10.14", "version": "1.10.15",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "d232901b09e67538e5c86a724be841bea5768a7c" "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/d232901b09e67538e5c86a724be841bea5768a7c", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/762c4dac4da6f8756eebb80e528c3a47855da9bd",
"reference": "d232901b09e67538e5c86a724be841bea5768a7c", "reference": "762c4dac4da6f8756eebb80e528c3a47855da9bd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1832,7 +1752,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-04-19T13:47:27+00:00" "time": "2023-05-09T15:28:01+00:00"
}, },
{ {
"name": "phpstan/phpstan-phpunit", "name": "phpstan/phpstan-phpunit",
@ -2255,16 +2175,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.6.7", "version": "9.6.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2" "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/17d621b3aff84d0c8b62539e269e87d8d5baa76e",
"reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2", "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2338,7 +2258,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7" "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.8"
}, },
"funding": [ "funding": [
{ {
@ -2354,7 +2274,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-04-14T08:58:40+00:00" "time": "2023-05-11T05:14:45+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@ -2656,16 +2576,16 @@
}, },
{ {
"name": "sebastian/diff", "name": "sebastian/diff",
"version": "4.0.4", "version": "4.0.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/diff.git", "url": "https://github.com/sebastianbergmann/diff.git",
"reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
"reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2710,7 +2630,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/diff/issues", "issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
}, },
"funding": [ "funding": [
{ {
@ -2718,7 +2638,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-10-26T13:10:38+00:00" "time": "2023-05-07T05:35:17+00:00"
}, },
{ {
"name": "sebastian/environment", "name": "sebastian/environment",
@ -3377,7 +3297,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.0", "php": "^8.1",
"php-64bit": "*", "php-64bit": "*",
"ext-chunkutils2": "^0.3.1", "ext-chunkutils2": "^0.3.1",
"ext-crypto": "^0.3.1", "ext-crypto": "^0.3.1",
@ -3406,7 +3326,7 @@
}, },
"platform-dev": [], "platform-dev": [],
"platform-overrides": { "platform-overrides": {
"php": "8.0.0" "php": "8.1.0"
}, },
"plugin-api-version": "2.3.0" "plugin-api-version": "2.3.0"
} }

View File

@ -85,8 +85,11 @@ network:
batch-threshold: 256 batch-threshold: 256
#Compression level used when sending batched packets. Higher = more CPU, less bandwidth usage #Compression level used when sending batched packets. Higher = more CPU, less bandwidth usage
compression-level: 6 compression-level: 6
#Use AsyncTasks for compression. Adds half/one tick delay, less CPU load on main thread #Use AsyncTasks for compression during the main game session. Increases latency, but may reduce main thread load
async-compression: false async-compression: false
#Threshold for async compression, in bytes. Only packets larger than this will be compressed asynchronously
#Due to large overhead of AsyncTask, async compression isn't worth it except for large packets
async-compression-threshold: 10000
#Experimental. Use UPnP to automatically port forward #Experimental. Use UPnP to automatically port forward
upnp-forwarding: false upnp-forwarding: false
#Maximum size in bytes of packets sent over the network (default 1492 bytes). Packets larger than this will be #Maximum size in bytes of packets sent over the network (default 1492 bytes). Packets larger than this will be

View File

@ -50,7 +50,7 @@ namespace pocketmine {
require_once __DIR__ . '/VersionInfo.php'; require_once __DIR__ . '/VersionInfo.php';
const MIN_PHP_VERSION = "8.0.0"; const MIN_PHP_VERSION = "8.1.0";
/** /**
* @param string $message * @param string $message
@ -265,9 +265,6 @@ JIT_WARNING
exit(1); exit(1);
} }
} }
if(extension_loaded('parallel')){
\parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH);
}
ErrorToExceptionHandler::set(); ErrorToExceptionHandler::set();

View File

@ -205,6 +205,8 @@ class Server{
private const TICKS_PER_TPS_OVERLOAD_WARNING = 5 * self::TARGET_TICKS_PER_SECOND; private const TICKS_PER_TPS_OVERLOAD_WARNING = 5 * self::TARGET_TICKS_PER_SECOND;
private const TICKS_PER_STATS_REPORT = 300 * self::TARGET_TICKS_PER_SECOND; private const TICKS_PER_STATS_REPORT = 300 * self::TARGET_TICKS_PER_SECOND;
private const DEFAULT_ASYNC_COMPRESSION_THRESHOLD = 10_000;
private static ?Server $instance = null; private static ?Server $instance = null;
private TimeTrackingSleeperHandler $tickSleeper; private TimeTrackingSleeperHandler $tickSleeper;
@ -263,6 +265,7 @@ class Server{
private Network $network; private Network $network;
private bool $networkCompressionAsync = true; private bool $networkCompressionAsync = true;
private int $networkCompressionAsyncThreshold = self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD;
private Language $language; private Language $language;
private bool $forceLanguage = false; private bool $forceLanguage = false;
@ -901,6 +904,10 @@ class Server{
ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE)); ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE));
$this->networkCompressionAsync = $this->configGroup->getPropertyBool("network.async-compression", true); $this->networkCompressionAsync = $this->configGroup->getPropertyBool("network.async-compression", true);
$this->networkCompressionAsyncThreshold = max(
$this->configGroup->getPropertyInt("network.async-compression-threshold", self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD),
$netCompressionThreshold ?? self::DEFAULT_ASYNC_COMPRESSION_THRESHOLD
);
EncryptionContext::$ENABLED = $this->configGroup->getPropertyBool("network.enable-encryption", true); EncryptionContext::$ENABLED = $this->configGroup->getPropertyBool("network.enable-encryption", true);
@ -1359,7 +1366,7 @@ class Server{
} }
$promise = new CompressBatchPromise(); $promise = new CompressBatchPromise();
if(!$sync){ if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){
$task = new CompressBatchTask($buffer, $promise, $compressor); $task = new CompressBatchTask($buffer, $promise, $compressor);
$this->asyncPool->submitTask($task); $this->asyncPool->submitTask($task);
}else{ }else{

View File

@ -106,7 +106,6 @@ use pocketmine\utils\BinaryDataException;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
use pocketmine\utils\ObjectSet; use pocketmine\utils\ObjectSet;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use pocketmine\world\Position; use pocketmine\world\Position;
use function array_map; use function array_map;
use function array_values; use function array_values;
@ -1049,8 +1048,6 @@ class NetworkSession{
* @phpstan-param \Closure() : void $onCompletion * @phpstan-param \Closure() : void $onCompletion
*/ */
public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{
Utils::validateCallableSignature(function() : void{}, $onCompletion);
$world = $this->player->getLocation()->getWorld(); $world = $this->player->getLocation()->getWorld();
ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve(

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\compression; namespace pocketmine\network\mcpe\compression;
use pocketmine\utils\Utils;
use function array_push; use function array_push;
class CompressBatchPromise{ class CompressBatchPromise{
@ -42,9 +41,6 @@ class CompressBatchPromise{
*/ */
public function onResolve(\Closure ...$callbacks) : void{ public function onResolve(\Closure ...$callbacks) : void{
$this->checkCancelled(); $this->checkCancelled();
foreach($callbacks as $callback){
Utils::validateCallableSignature(function(CompressBatchPromise $promise) : void{}, $callback);
}
if($this->result !== null){ if($this->result !== null){
foreach($callbacks as $callback){ foreach($callbacks as $callback){
$callback($this); $callback($this);

View File

@ -1192,7 +1192,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* TODO: make this a dynamic ability instead of being hardcoded * TODO: make this a dynamic ability instead of being hardcoded
*/ */
public function hasFiniteResources() : bool{ public function hasFiniteResources() : bool{
return $this->gamemode->equals(GameMode::SURVIVAL()) || $this->gamemode->equals(GameMode::ADVENTURE()); return !$this->gamemode->equals(GameMode::CREATIVE());
} }
public function isFireProof() : bool{ public function isFireProof() : bool{
@ -1685,7 +1685,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$ev = new PlayerBlockPickEvent($this, $block, $item); $ev = new PlayerBlockPickEvent($this, $block, $item);
$existingSlot = $this->inventory->first($item); $existingSlot = $this->inventory->first($item);
if($existingSlot === -1 && ($this->hasFiniteResources() || $this->isSpectator())){ if($existingSlot === -1 && $this->hasFiniteResources()){
$ev->cancel(); $ev->cancel();
} }
$ev->call(); $ev->call();

View File

@ -242,7 +242,6 @@ class AsyncPool{
while(!$queue->isEmpty()){ while(!$queue->isEmpty()){
/** @var AsyncTask $task */ /** @var AsyncTask $task */
$task = $queue->bottom(); $task = $queue->bottom();
$task->checkProgressUpdates();
if($task->isFinished()){ //make sure the task actually executed before trying to collect if($task->isFinished()){ //make sure the task actually executed before trying to collect
$queue->dequeue(); $queue->dequeue();
@ -263,6 +262,7 @@ class AsyncPool{
$task->onCompletion(); $task->onCompletion();
} }
}else{ }else{
$task->checkProgressUpdates();
$more = true; $more = true;
break; //current task is still running, skip to next worker break; //current task is still running, skip to next worker
} }

View File

@ -59,10 +59,6 @@ abstract class Timings{
public static TimingsHandler $connection; public static TimingsHandler $connection;
public static TimingsHandler $scheduler; public static TimingsHandler $scheduler;
public static TimingsHandler $serverCommand; public static TimingsHandler $serverCommand;
public static TimingsHandler $worldLoad;
public static TimingsHandler $worldSave;
public static TimingsHandler $population;
public static TimingsHandler $generationCallback;
public static TimingsHandler $permissibleCalculation; public static TimingsHandler $permissibleCalculation;
public static TimingsHandler $permissibleCalculationDiff; public static TimingsHandler $permissibleCalculationDiff;
public static TimingsHandler $permissibleCalculationCallback; public static TimingsHandler $permissibleCalculationCallback;
@ -71,8 +67,6 @@ abstract class Timings{
public static TimingsHandler $projectileMove; public static TimingsHandler $projectileMove;
public static TimingsHandler $projectileMoveRayTrace; public static TimingsHandler $projectileMoveRayTrace;
public static TimingsHandler $playerCheckNearEntities; public static TimingsHandler $playerCheckNearEntities;
public static TimingsHandler $tickEntity;
public static TimingsHandler $tickTileEntity;
public static TimingsHandler $entityBaseTick; public static TimingsHandler $entityBaseTick;
public static TimingsHandler $livingEntityBaseTick; public static TimingsHandler $livingEntityBaseTick;
public static TimingsHandler $itemEntityBaseTick; public static TimingsHandler $itemEntityBaseTick;
@ -155,10 +149,6 @@ abstract class Timings{
self::$playerChunkSend = new TimingsHandler("Player Network Send - Chunks", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN); self::$playerChunkSend = new TimingsHandler("Player Network Send - Chunks", self::$playerNetworkSend, group: self::GROUP_BREAKDOWN);
self::$scheduler = new TimingsHandler("Scheduler"); self::$scheduler = new TimingsHandler("Scheduler");
self::$serverCommand = new TimingsHandler("Server Command"); self::$serverCommand = new TimingsHandler("Server Command");
self::$worldLoad = new TimingsHandler("World Load");
self::$worldSave = new TimingsHandler("World Save");
self::$population = new TimingsHandler("World Population");
self::$generationCallback = new TimingsHandler("World Generation Callback");
self::$permissibleCalculation = new TimingsHandler("Permissible Calculation"); self::$permissibleCalculation = new TimingsHandler("Permissible Calculation");
self::$permissibleCalculationDiff = new TimingsHandler("Permissible Calculation - Diff", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN); self::$permissibleCalculationDiff = new TimingsHandler("Permissible Calculation - Diff", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN);
self::$permissibleCalculationCallback = new TimingsHandler("Permissible Calculation - Callbacks", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN); self::$permissibleCalculationCallback = new TimingsHandler("Permissible Calculation - Callbacks", self::$permissibleCalculation, group: self::GROUP_BREAKDOWN);
@ -173,9 +163,6 @@ abstract class Timings{
self::$projectileMoveRayTrace = new TimingsHandler("Projectile Movement - Ray Tracing", self::$projectileMove, group: self::GROUP_BREAKDOWN); self::$projectileMoveRayTrace = new TimingsHandler("Projectile Movement - Ray Tracing", self::$projectileMove, group: self::GROUP_BREAKDOWN);
self::$playerCheckNearEntities = new TimingsHandler("checkNearEntities", group: self::GROUP_BREAKDOWN); self::$playerCheckNearEntities = new TimingsHandler("checkNearEntities", group: self::GROUP_BREAKDOWN);
self::$tickEntity = new TimingsHandler("Entity Tick", group: self::GROUP_BREAKDOWN);
self::$tickTileEntity = new TimingsHandler("Block Entity Tick", group: self::GROUP_BREAKDOWN);
self::$entityBaseTick = new TimingsHandler("Entity Base Tick", group: self::GROUP_BREAKDOWN); self::$entityBaseTick = new TimingsHandler("Entity Base Tick", group: self::GROUP_BREAKDOWN);
self::$livingEntityBaseTick = new TimingsHandler("Entity Base Tick - Living", group: self::GROUP_BREAKDOWN); self::$livingEntityBaseTick = new TimingsHandler("Entity Base Tick - Living", group: self::GROUP_BREAKDOWN);
self::$itemEntityBaseTick = new TimingsHandler("Entity Base Tick - ItemEntity", group: self::GROUP_BREAKDOWN); self::$itemEntityBaseTick = new TimingsHandler("Entity Base Tick - ItemEntity", group: self::GROUP_BREAKDOWN);
@ -226,7 +213,7 @@ abstract class Timings{
}else{ }else{
$displayName = self::shortenCoreClassName($entity::class, "pocketmine\\entity\\"); $displayName = self::shortenCoreClassName($entity::class, "pocketmine\\entity\\");
} }
self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, self::$tickEntity, group: self::GROUP_BREAKDOWN); self::$entityTypeTimingMap[$entity::class] = new TimingsHandler("Entity Tick - " . $displayName, group: self::GROUP_BREAKDOWN);
} }
return self::$entityTypeTimingMap[$entity::class]; return self::$entityTypeTimingMap[$entity::class];
@ -237,7 +224,6 @@ abstract class Timings{
if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){ if(!isset(self::$tileEntityTypeTimingMap[$tile::class])){
self::$tileEntityTypeTimingMap[$tile::class] = new TimingsHandler( self::$tileEntityTypeTimingMap[$tile::class] = new TimingsHandler(
"Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\"), "Block Entity Tick - " . self::shortenCoreClassName($tile::class, "pocketmine\\block\\tile\\"),
self::$tickTileEntity,
group: self::GROUP_BREAKDOWN group: self::GROUP_BREAKDOWN
); );
} }

View File

@ -30,7 +30,7 @@ use function implode;
use function spl_object_id; use function spl_object_id;
class TimingsHandler{ class TimingsHandler{
private const FORMAT_VERSION = 1; private const FORMAT_VERSION = 2; //peak timings fix
private static bool $enabled = false; private static bool $enabled = false;
private static int $timingStart = 0; private static int $timingStart = 0;

View File

@ -66,9 +66,6 @@ final class TimingsRecord{
if($record->curTickTotal > Server::TARGET_NANOSECONDS_PER_TICK){ if($record->curTickTotal > Server::TARGET_NANOSECONDS_PER_TICK){
$record->violations += (int) floor($record->curTickTotal / Server::TARGET_NANOSECONDS_PER_TICK); $record->violations += (int) floor($record->curTickTotal / Server::TARGET_NANOSECONDS_PER_TICK);
} }
if($record->curTickTotal > $record->peakTime){
$record->peakTime = $record->curTickTotal;
}
$record->curTickTotal = 0; $record->curTickTotal = 0;
$record->curCount = 0; $record->curCount = 0;
$record->ticksActive++; $record->ticksActive++;
@ -126,7 +123,7 @@ final class TimingsRecord{
public function getTicksActive() : int{ return $this->ticksActive; } public function getTicksActive() : int{ return $this->ticksActive; }
public function getPeakTime() : float{ return $this->peakTime; } public function getPeakTime() : int{ return $this->peakTime; }
public function startTiming(int $now) : void{ public function startTiming(int $now) : void{
$this->start = $now; $this->start = $now;
@ -152,6 +149,9 @@ final class TimingsRecord{
++$this->curCount; ++$this->curCount;
++$this->count; ++$this->count;
$this->start = 0; $this->start = 0;
if($diff > $this->peakTime){
$this->peakTime = $diff;
}
} }
public static function getCurrentRecord() : ?self{ public static function getCurrentRecord() : ?self{

View File

@ -79,7 +79,6 @@ use pocketmine\promise\PromiseResolver;
use pocketmine\scheduler\AsyncPool; use pocketmine\scheduler\AsyncPool;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\ServerConfigGroup; use pocketmine\ServerConfigGroup;
use pocketmine\timings\Timings;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Limits; use pocketmine\utils\Limits;
use pocketmine\utils\ReversePriorityQueue; use pocketmine\utils\ReversePriorityQueue;
@ -980,7 +979,6 @@ class World implements ChunkManager{
$this->timings->entityTick->startTiming(); $this->timings->entityTick->startTiming();
//Update entities that need update //Update entities that need update
Timings::$tickEntity->startTiming();
foreach($this->updateEntities as $id => $entity){ foreach($this->updateEntities as $id => $entity){
if($entity->isClosed() || $entity->isFlaggedForDespawn() || !$entity->onUpdate($currentTick)){ if($entity->isClosed() || $entity->isFlaggedForDespawn() || !$entity->onUpdate($currentTick)){
unset($this->updateEntities[$id]); unset($this->updateEntities[$id]);
@ -989,7 +987,6 @@ class World implements ChunkManager{
$entity->close(); $entity->close();
} }
} }
Timings::$tickEntity->stopTiming();
$this->timings->entityTick->stopTiming(); $this->timings->entityTick->stopTiming();
$this->timings->randomChunkUpdates->startTiming(); $this->timings->randomChunkUpdates->startTiming();
@ -1385,10 +1382,15 @@ class World implements ChunkManager{
(new WorldSaveEvent($this))->call(); (new WorldSaveEvent($this))->call();
$timings = $this->timings->syncDataSave;
$timings->startTiming();
$this->provider->getWorldData()->setTime($this->time); $this->provider->getWorldData()->setTime($this->time);
$this->saveChunks(); $this->saveChunks();
$this->provider->getWorldData()->save(); $this->provider->getWorldData()->save();
$timings->stopTiming();
return true; return true;
} }
@ -3191,7 +3193,8 @@ class World implements ChunkManager{
private function internalOrderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader, ?PromiseResolver $resolver) : Promise{ private function internalOrderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader, ?PromiseResolver $resolver) : Promise{
$chunkHash = World::chunkHash($chunkX, $chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ);
Timings::$population->startTiming(); $timings = $this->timings->chunkPopulationOrder;
$timings->startTiming();
try{ try{
for($xx = -1; $xx <= 1; ++$xx){ for($xx = -1; $xx <= 1; ++$xx){
@ -3248,7 +3251,7 @@ class World implements ChunkManager{
return $resolver->getPromise(); return $resolver->getPromise();
}finally{ }finally{
Timings::$population->stopTiming(); $timings->stopTiming();
} }
} }
@ -3257,7 +3260,8 @@ class World implements ChunkManager{
* @phpstan-param array<int, Chunk> $adjacentChunks * @phpstan-param array<int, Chunk> $adjacentChunks
*/ */
private function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ private function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{
Timings::$generationCallback->startTiming(); $timings = $this->timings->chunkPopulationCompletion;
$timings->startTiming();
$dirtyChunks = 0; $dirtyChunks = 0;
for($xx = -1; $xx <= 1; ++$xx){ for($xx = -1; $xx <= 1; ++$xx){
@ -3326,7 +3330,7 @@ class World implements ChunkManager{
$this->drainPopulationRequestQueue(); $this->drainPopulationRequestQueue();
} }
Timings::$generationCallback->stopTiming(); $timings->stopTiming();
} }
public function doChunkGarbageCollection() : void{ public function doChunkGarbageCollection() : void{

View File

@ -30,7 +30,6 @@ use pocketmine\event\world\WorldUnloadEvent;
use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationFactory;
use pocketmine\player\ChunkSelector; use pocketmine\player\ChunkSelector;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\timings\Timings;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\CorruptedWorldException;
use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException;
@ -393,7 +392,6 @@ class WorldManager{
} }
private function doAutoSave() : void{ private function doAutoSave() : void{
Timings::$worldSave->startTiming();
foreach($this->worlds as $world){ foreach($this->worlds as $world){
foreach($world->getPlayers() as $player){ foreach($world->getPlayers() as $player){
if($player->spawned){ if($player->spawned){
@ -402,6 +400,5 @@ class WorldManager{
} }
$world->save(false); $world->save(false);
} }
Timings::$worldSave->stopTiming();
} }
} }

View File

@ -38,6 +38,7 @@ class WorldTimings{
public TimingsHandler $randomChunkUpdatesChunkSelection; public TimingsHandler $randomChunkUpdatesChunkSelection;
public TimingsHandler $doChunkGC; public TimingsHandler $doChunkGC;
public TimingsHandler $entityTick; public TimingsHandler $entityTick;
public TimingsHandler $tileTick;
public TimingsHandler $doTick; public TimingsHandler $doTick;
public TimingsHandler $syncChunkSend; public TimingsHandler $syncChunkSend;
@ -48,33 +49,54 @@ class WorldTimings{
public TimingsHandler $syncChunkLoadFixInvalidBlocks; public TimingsHandler $syncChunkLoadFixInvalidBlocks;
public TimingsHandler $syncChunkLoadEntities; public TimingsHandler $syncChunkLoadEntities;
public TimingsHandler $syncChunkLoadTileEntities; public TimingsHandler $syncChunkLoadTileEntities;
public TimingsHandler $syncDataSave;
public TimingsHandler $syncChunkSave; public TimingsHandler $syncChunkSave;
public TimingsHandler $chunkPopulationOrder;
public TimingsHandler $chunkPopulationCompletion;
/**
* @var TimingsHandler[]
* @phpstan-var array<string, TimingsHandler>
*/
private static array $aggregators = [];
private static function newTimer(string $worldName, string $timerName) : TimingsHandler{
$aggregator = self::$aggregators[$timerName] ??= new TimingsHandler("Worlds - $timerName"); //displayed in Minecraft primary table
return new TimingsHandler("$worldName - $timerName", $aggregator, Timings::GROUP_BREAKDOWN);
}
public function __construct(World $world){ public function __construct(World $world){
$name = $world->getFolderName() . " - "; $name = $world->getFolderName();
$this->setBlock = new TimingsHandler($name . "setBlock", group: Timings::GROUP_BREAKDOWN); $this->setBlock = self::newTimer($name, "Set Blocks");
$this->doBlockLightUpdates = new TimingsHandler($name . "Block Light Updates", group: Timings::GROUP_BREAKDOWN); $this->doBlockLightUpdates = self::newTimer($name, "Block Light Updates");
$this->doBlockSkyLightUpdates = new TimingsHandler($name . "Sky Light Updates", group: Timings::GROUP_BREAKDOWN); $this->doBlockSkyLightUpdates = self::newTimer($name, "Sky Light Updates");
$this->doChunkUnload = new TimingsHandler($name . "Unload Chunks", group: Timings::GROUP_BREAKDOWN); $this->doChunkUnload = self::newTimer($name, "Unload Chunks");
$this->scheduledBlockUpdates = new TimingsHandler($name . "Scheduled Block Updates", group: Timings::GROUP_BREAKDOWN); $this->scheduledBlockUpdates = self::newTimer($name, "Scheduled Block Updates");
$this->randomChunkUpdates = new TimingsHandler($name . "Random Chunk Updates", group: Timings::GROUP_BREAKDOWN); $this->randomChunkUpdates = self::newTimer($name, "Random Chunk Updates");
$this->randomChunkUpdatesChunkSelection = new TimingsHandler($name . "Random Chunk Updates - Chunk Selection", group: Timings::GROUP_BREAKDOWN); $this->randomChunkUpdatesChunkSelection = self::newTimer($name, "Random Chunk Updates - Chunk Selection");
$this->doChunkGC = new TimingsHandler($name . "Garbage Collection", group: Timings::GROUP_BREAKDOWN); $this->doChunkGC = self::newTimer($name, "Garbage Collection");
$this->entityTick = new TimingsHandler($name . "Tick Entities", group: Timings::GROUP_BREAKDOWN); $this->entityTick = self::newTimer($name, "Entity Tick");
$this->tileTick = self::newTimer($name, "Block Entity Tick");
$this->doTick = self::newTimer($name, "World Tick");
Timings::init(); //make sure the timers we want are available $this->syncChunkSend = self::newTimer($name, "Player Send Chunks");
$this->syncChunkSend = new TimingsHandler($name . "Player Send Chunks", Timings::$playerChunkSend, group: Timings::GROUP_BREAKDOWN); $this->syncChunkSendPrepare = self::newTimer($name, "Player Send Chunk Prepare");
$this->syncChunkSendPrepare = new TimingsHandler($name . "Player Send Chunk Prepare", Timings::$playerChunkSend, group: Timings::GROUP_BREAKDOWN);
$this->syncChunkLoad = new TimingsHandler($name . "Chunk Load", Timings::$worldLoad, group: Timings::GROUP_BREAKDOWN); $this->syncChunkLoad = self::newTimer($name, "Chunk Load");
$this->syncChunkLoadData = new TimingsHandler($name . "Chunk Load - Data", group: Timings::GROUP_BREAKDOWN); $this->syncChunkLoadData = self::newTimer($name, "Chunk Load - Data");
$this->syncChunkLoadFixInvalidBlocks = new TimingsHandler($name . "Chunk Load - Fix Invalid Blocks", group: Timings::GROUP_BREAKDOWN); $this->syncChunkLoadFixInvalidBlocks = self::newTimer($name, "Chunk Load - Fix Invalid Blocks");
$this->syncChunkLoadEntities = new TimingsHandler($name . "Chunk Load - Entities", group: Timings::GROUP_BREAKDOWN); $this->syncChunkLoadEntities = self::newTimer($name, "Chunk Load - Entities");
$this->syncChunkLoadTileEntities = new TimingsHandler($name . "Chunk Load - TileEntities", group: Timings::GROUP_BREAKDOWN); $this->syncChunkLoadTileEntities = self::newTimer($name, "Chunk Load - Block Entities");
$this->syncChunkSave = new TimingsHandler($name . "Chunk Save", Timings::$worldSave, group: Timings::GROUP_BREAKDOWN);
$this->doTick = new TimingsHandler($name . "World Tick"); $this->syncDataSave = self::newTimer($name, "Data Save");
$this->syncChunkSave = self::newTimer($name, "Chunk Save");
$this->chunkPopulationOrder = self::newTimer($name, "Chunk Population - Order");
$this->chunkPopulationCompletion = self::newTimer($name, "Chunk Population - Completion");
} }
} }