mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-12 12:25:09 +00:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
b095f606c1 | |||
b312e93176 | |||
61933624d2 | |||
90beaeaeb4 | |||
466f7e98ed | |||
59be901efe | |||
5d2b0acfc8 | |||
7d1d62042c | |||
17dde140a5 | |||
1e5597f0d5 | |||
97ef209c5f | |||
1305fd5fb2 | |||
7a137f932f | |||
63e8b1cf3a | |||
65bce762ff | |||
529700bb8b | |||
437fa615b8 | |||
0ee6cdb058 | |||
97d6a79b25 | |||
8b5e4c1c16 | |||
214a5ddc15 | |||
9f7dfe3355 | |||
9b55d18393 | |||
31465525e3 | |||
74613b9b09 | |||
1cefe24414 | |||
8bf85d4a18 | |||
b5e6dec0c6 | |||
a3306914cc | |||
3b32ea1b0b | |||
7ec32f981e | |||
b0c87e9d06 | |||
99996b62d6 | |||
1cb6d9f5af | |||
0a9b52618d | |||
7ae6425d05 | |||
b5cfab497d | |||
774e23137e | |||
43bc3c7b25 | |||
eb62dc3294 | |||
279056fe2f | |||
cd233b123b | |||
64dd5e3bf6 | |||
4e5cc57560 | |||
95263795a8 | |||
2db86d151f | |||
f0358b09b7 | |||
80a432d9ff | |||
ec9f9a469f | |||
5e92f55d35 | |||
58c1bfe5d2 |
2
.github/workflows/draft-release.yml
vendored
2
.github/workflows/draft-release.yml
vendored
@ -69,7 +69,7 @@ jobs:
|
||||
${{ github.workspace }}/build_info.json
|
||||
|
||||
- name: Create draft release
|
||||
uses: ncipollo/release-action@v1.11.1
|
||||
uses: ncipollo/release-action@v1.12.0
|
||||
with:
|
||||
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
|
||||
commit: ${{ github.sha }}
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -199,6 +199,8 @@ jobs:
|
||||
with:
|
||||
php-version: 8.0
|
||||
tools: php-cs-fixer:3.11
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run PHP-CS-Fixer
|
||||
run: php-cs-fixer fix --dry-run --diff --ansi
|
||||
|
2
.github/workflows/support.yml
vendored
2
.github/workflows/support.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
||||
support:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/support-requests@v2
|
||||
- uses: dessant/support-requests@v3
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
support-label: "Support request"
|
||||
|
5
.idea/codeStyles/Project.xml
generated
5
.idea/codeStyles/Project.xml
generated
@ -62,6 +62,11 @@
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Shell Script">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="neon">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
|
@ -66,6 +66,9 @@ BODY,
|
||||
],
|
||||
'indentation_type' => true,
|
||||
'logical_operators' => true,
|
||||
'native_constant_invocation' => [
|
||||
'scope' => 'namespaced'
|
||||
],
|
||||
'native_function_invocation' => [
|
||||
'scope' => 'namespaced',
|
||||
'include' => ['@all'],
|
||||
@ -92,6 +95,12 @@ BODY,
|
||||
],
|
||||
'sort_algorithm' => 'alpha'
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'vertical',
|
||||
'tags' => [
|
||||
'param',
|
||||
]
|
||||
],
|
||||
'phpdoc_line_span' => [
|
||||
'property' => 'single',
|
||||
'method' => null,
|
||||
|
@ -39,6 +39,7 @@ use function sprintf;
|
||||
use function str_replace;
|
||||
use function substr;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "Provide a path to process\n");
|
||||
|
Submodule build/php updated: 9353116fa8...6b605ed7c4
@ -40,12 +40,13 @@ use function rtrim;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function unlink;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const PHP_EOL;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @param string[] $strings
|
||||
* @param string[] $strings
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
|
@ -36,3 +36,18 @@ Released 7th November 2022.
|
||||
- Added validation for the array given to `BaseInventory->setContents()` to ensure that it contains only `Item` instances.
|
||||
- Silenced `PlayerAuthInputPacket` spam when the session is in the "spawn response" state.
|
||||
- Updated to PHPStan 1.9.
|
||||
|
||||
# 4.10.2
|
||||
Released 25th November 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed crashes on macOS and Linux when using console colours without the `TERM` environment variable set.
|
||||
- Fixed crashdumps not being generated when error messages contained invalid UTF-8 characters.
|
||||
|
||||
## Documentation
|
||||
- Clarified documentation of caching behaviour for `Internet::getIP()`.
|
||||
- Added and improved documentation for many `Inventory` methods.
|
||||
- Rewritten documentation for `PlayerCreationEvent` with warnings and more detail.
|
||||
|
||||
## Internals
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
||||
|
@ -92,11 +92,15 @@ Released 25th November 2022.
|
||||
- `ItemFrameRotateItemSound`
|
||||
|
||||
## Internals
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. (24e72ec109c1442b09558df89b6833cf2f2e0ec7)
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). (2940547026db40ce76deb46e992870de3ead79ad)
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. (e90abecf38d9c57635fa0497514bba7e546a2469)
|
||||
- Console polling is now done on the main thread (no longer a performance concern).
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie.
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged.
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused.
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. ([link](https://github.com/pmmp/PocketMine-MP/commits/24e72ec109c1442b09558df89b6833cf2f2e0ec7))
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). ([link](https://github.com/pmmp/PocketMine-MP/commit/2940547026db40ce76deb46e992870de3ead79ad))
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. ([link](https://github.com/pmmp/PocketMine-MP/commit/e90abecf38d9c57635fa0497514bba7e546a2469))
|
||||
- Inventories are now mapped on a per-slot basis. This means that more than one inventory can be mapped to the same window ID, which is necessary for correctly handling "UI" inventories like crafting tables.
|
||||
- `InventoryManager->getWindow(int $windowId) : ?Inventory` is replaced by `locateWindowAndSlot` (see below).
|
||||
- Added `InventoryManager->locateWindowAndSlot(int $windowId, int $netSlotId) : array{Inventory, int}` - accepts a window ID and absolute slot ID, and returns the associated inventory and the slot relative to the inventory's own start (for use with `getItem()` etc.).
|
||||
- Slot offset mapping for "UI" inventories is now handled in `InventoryManager->createComplexSlotMapping()` instead of in `TypeConverter`.
|
||||
- Console polling is now done on the main thread (no longer a performance concern). ([link](https://github.com/pmmp/PocketMine-MP/commit/b3f03d7ae645de67a54b7300c09b94eeca16298e))
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie. ([link](https://github.com/pmmp/PocketMine-MP/commit/2585160ca2c4df5758b8b980331307402ff9f0fb))
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged. ([link](https://github.com/pmmp/PocketMine-MP/commit/83e5b0adb6fa0dddec377182bb1c7945ac8f7820))
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused. ([link](https://github.com/pmmp/PocketMine-MP/commit/3feaa18f6c10c3a99c0deca75f57ec2d74b92ab4))
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
46
changelogs/4.12.md
Normal file
46
changelogs/4.12.md
Normal file
@ -0,0 +1,46 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.50**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.12.0
|
||||
Released 30th November 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.50.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.12.1
|
||||
Released 4th December 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed items glitching when dragging a stack of items across the crafting grid (desync issues).
|
||||
|
||||
# 4.12.2
|
||||
Released 15th December 2022.
|
||||
|
||||
## Fixes
|
||||
- Folder used for plugins (optionally specified by `--plugins`) is no longer required to be writable.
|
||||
- Fixed broken writable check for server data folder (`is_writable()` broken on NFS and similar filesystems).
|
||||
- `Filesystem::createLockFile()` exceptions now include more information about why the lock file could not be created.
|
||||
- Fixed client-side item predictions not being rolled back when cancelling events such as `PlayerItemUseEvent`.
|
||||
|
||||
## Dependencies
|
||||
- Updated BedrockProtocol to [17.1.0](https://github.com/pmmp/BedrockProtocol/releases/tag/17.1.0+bedrock-1.19.50). This adds some missing `LevelSoundEvent` constants and fixes the values for `ContainerUIIds`.
|
||||
|
||||
# 4.12.3
|
||||
Released 28th December 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed unauthenticated connections taking up player count slots, preventing players from joining.
|
||||
- Fixed a possible crash in `World->tickChunk()` when plugins unload chunks during some events.
|
||||
- `/gamemode` will now report a failure to change game mode if the player is already in the requested game mode.
|
||||
|
||||
# 4.12.4
|
||||
Released 3rd January 2023.
|
||||
|
||||
## Fixes
|
||||
- Added workarounds for an active exploit being used to deny service to servers.
|
@ -34,8 +34,8 @@
|
||||
"adhocore/json-comment": "^1.1",
|
||||
"fgrosse/phpasn1": "^2.3",
|
||||
"netresearch/jsonmapper": "^4.0",
|
||||
"pocketmine/bedrock-data": "~1.12.0+bedrock-1.19.40",
|
||||
"pocketmine/bedrock-protocol": "~16.0.0+bedrock-1.19.40",
|
||||
"pocketmine/bedrock-data": "~1.13.0+bedrock-1.19.50",
|
||||
"pocketmine/bedrock-protocol": "~17.1.0+bedrock-1.19.50",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
@ -54,7 +54,7 @@
|
||||
"webmozart/path-util": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.2",
|
||||
"phpstan/phpstan": "1.9.4",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
107
composer.lock
generated
107
composer.lock
generated
@ -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": "ff2bc73e9b0acccb1e63ddef2412fe31",
|
||||
"content-hash": "393c7921d03d080d3ef3b836f90b4415",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -123,24 +123,24 @@
|
||||
},
|
||||
{
|
||||
"name": "fgrosse/phpasn1",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fgrosse/PHPASN1.git",
|
||||
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296"
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/eef488991d53e58e60c9554b09b1201ca5ba9296",
|
||||
"reference": "eef488991d53e58e60c9554b09b1201ca5ba9296",
|
||||
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0"
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "~2.0",
|
||||
"phpunit/phpunit": "^6.3 || ^7.0 || ^8.0"
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "BCmath is the fallback extension for big integer calculations",
|
||||
@ -192,22 +192,23 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fgrosse/PHPASN1/issues",
|
||||
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.4.0"
|
||||
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0"
|
||||
},
|
||||
"time": "2021-12-11T12:41:06+00:00"
|
||||
"abandoned": true,
|
||||
"time": "2022-12-19T11:08:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v4.0.0",
|
||||
"version": "v4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d"
|
||||
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
||||
"reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||
"reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -243,22 +244,22 @@
|
||||
"support": {
|
||||
"email": "cweiske@cweiske.de",
|
||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0"
|
||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0"
|
||||
},
|
||||
"time": "2020-12-01T19:48:11+00:00"
|
||||
"time": "2022-12-08T20:46:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-data",
|
||||
"version": "1.12.0+bedrock-1.19.40",
|
||||
"version": "1.13.0+bedrock-1.19.50",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "32690f1dac05608b558fe7c40b6d634772c8e416"
|
||||
"reference": "57337ddc9433a0e245a1ce48c51af05f0573d58d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/32690f1dac05608b558fe7c40b6d634772c8e416",
|
||||
"reference": "32690f1dac05608b558fe7c40b6d634772c8e416",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/57337ddc9433a0e245a1ce48c51af05f0573d58d",
|
||||
"reference": "57337ddc9433a0e245a1ce48c51af05f0573d58d",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -269,22 +270,22 @@
|
||||
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockData/issues",
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.19.40"
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.19.50"
|
||||
},
|
||||
"time": "2022-10-25T21:45:24+00:00"
|
||||
"time": "2022-11-30T16:19:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-protocol",
|
||||
"version": "16.0.0+bedrock-1.19.40",
|
||||
"version": "17.1.0+bedrock-1.19.50",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockProtocol.git",
|
||||
"reference": "ce900ffa6a4cc07af92686f27d580dd2e2541382"
|
||||
"reference": "c572706cf5e3202718dd35a35dd30fe08cd671de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ce900ffa6a4cc07af92686f27d580dd2e2541382",
|
||||
"reference": "ce900ffa6a4cc07af92686f27d580dd2e2541382",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c572706cf5e3202718dd35a35dd30fe08cd671de",
|
||||
"reference": "c572706cf5e3202718dd35a35dd30fe08cd671de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -298,7 +299,7 @@
|
||||
"ramsey/uuid": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.0",
|
||||
"phpstan/phpstan": "1.9.3",
|
||||
"phpstan/phpstan-phpunit": "^1.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
@ -316,9 +317,9 @@
|
||||
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockProtocol/issues",
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/16.0.0+bedrock-1.19.40"
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/17.1.0+bedrock-1.19.50"
|
||||
},
|
||||
"time": "2022-11-19T16:11:48+00:00"
|
||||
"time": "2022-12-15T20:34:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
@ -1820,16 +1821,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.9.2",
|
||||
"version": "1.9.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa"
|
||||
"reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/d6fdf01c53978b6429f1393ba4afeca39cc68afa",
|
||||
"reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2",
|
||||
"reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1859,7 +1860,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.2"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.9.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1875,25 +1876,25 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-10T09:56:11+00:00"
|
||||
"time": "2022-12-17T13:33:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
"version": "1.2.2",
|
||||
"version": "1.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan-phpunit.git",
|
||||
"reference": "dea1f87344c6964c607d9076dee42d891f3923f0"
|
||||
"reference": "54a24bd23e9e80ee918cdc24f909d376c2e273f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/dea1f87344c6964c607d9076dee42d891f3923f0",
|
||||
"reference": "dea1f87344c6964c607d9076dee42d891f3923f0",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/54a24bd23e9e80ee918cdc24f909d376c2e273f7",
|
||||
"reference": "54a24bd23e9e80ee918cdc24f909d376c2e273f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpstan": "^1.8.11"
|
||||
"phpstan/phpstan": "^1.9.3"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<7.0"
|
||||
@ -1925,9 +1926,9 @@
|
||||
"description": "PHPUnit extensions and rules for PHPStan",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.2.2"
|
||||
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.3"
|
||||
},
|
||||
"time": "2022-10-28T10:23:07+00:00"
|
||||
"time": "2022-12-21T15:25:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-strict-rules",
|
||||
@ -1979,16 +1980,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.19",
|
||||
"version": "9.2.22",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559"
|
||||
"reference": "e4bf60d2220b4baaa0572986b5d69870226b06df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559",
|
||||
"reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df",
|
||||
"reference": "e4bf60d2220b4baaa0572986b5d69870226b06df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2044,7 +2045,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2052,7 +2053,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-18T07:47:47+00:00"
|
||||
"time": "2022-12-18T16:40:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@ -2297,16 +2298,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.26",
|
||||
"version": "9.5.27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2"
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2",
|
||||
"reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"reference": "a2bc7ffdca99f92d959b3f2270529334030bba38",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2379,7 +2380,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2395,7 +2396,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-28T06:00:21+00:00"
|
||||
"time": "2022-12-09T07:31:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
@ -286,7 +286,7 @@ class MemoryManager{
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
* @param mixed $startingObject
|
||||
*/
|
||||
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
$hardLimit = Utils::assumeNotFalse(ini_get('memory_limit'), "memory_limit INI directive should always exist");
|
||||
@ -480,7 +480,7 @@ class MemoryManager{
|
||||
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param object[] $objects reference parameter
|
||||
* @param object[] $objects reference parameter
|
||||
* @param int[] $refCounts reference parameter
|
||||
*
|
||||
* @phpstan-param array<string, object> $objects
|
||||
|
@ -39,11 +39,14 @@ namespace pocketmine {
|
||||
use function extension_loaded;
|
||||
use function function_exists;
|
||||
use function getcwd;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use function phpversion;
|
||||
use function preg_match;
|
||||
use function preg_quote;
|
||||
use function realpath;
|
||||
use function version_compare;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
require_once __DIR__ . '/VersionInfo.php';
|
||||
|
||||
@ -273,25 +276,33 @@ JIT_WARNING
|
||||
$pluginPath = getopt_string("plugins") ?? $cwd . DIRECTORY_SEPARATOR . "plugins";
|
||||
Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX);
|
||||
|
||||
if(!@mkdir($dataPath, 0777, true) && (!is_dir($dataPath) || !is_writable($dataPath))){
|
||||
if(!@mkdir($dataPath, 0777, true) && !is_dir($dataPath)){
|
||||
critical_error("Unable to create/access data directory at $dataPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
//this has to be done after we're sure the data path exists
|
||||
$dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
|
||||
if(!@mkdir($pluginPath, 0777, true) && (!is_dir($pluginPath) || !is_writable($pluginPath))){
|
||||
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$lockFilePath = Path::join($dataPath, 'server.lock');
|
||||
if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){
|
||||
try{
|
||||
$pid = Filesystem::createLockFile($lockFilePath);
|
||||
}catch(\InvalidArgumentException $e){
|
||||
critical_error($e->getMessage());
|
||||
critical_error("Please ensure that there is enough space on the disk and that the current user has read/write permissions to the selected data directory $dataPath.");
|
||||
exit(1);
|
||||
}
|
||||
if($pid !== null){
|
||||
critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ").");
|
||||
critical_error("Please stop the other server first before running a new one.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!@mkdir($pluginPath, 0777, true) && !is_dir($pluginPath)){
|
||||
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
//Logger has a dependency on timezone
|
||||
Timezone::init();
|
||||
|
||||
|
@ -1268,7 +1268,7 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandSender[]|null $recipients
|
||||
* @param CommandSender[]|null $recipients
|
||||
*/
|
||||
public function broadcastMessage(Translatable|string $message, ?array $recipients = null) : int{
|
||||
$recipients = $recipients ?? $this->getBroadcastChannelSubscribers(self::BROADCAST_CHANNEL_USERS);
|
||||
@ -1321,9 +1321,9 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
* @param Player[]|null $recipients
|
||||
*/
|
||||
public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, ?array $recipients = null) : int{
|
||||
|
@ -44,7 +44,7 @@ final class ServerConfigGroup{
|
||||
){}
|
||||
|
||||
/**
|
||||
* @param mixed $defaultValue
|
||||
* @param mixed $defaultValue
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.11.0";
|
||||
public const BASE_VERSION = "4.12.4";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
|
@ -87,7 +87,7 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
*
|
||||
* @phpstan-param list<BannerPatternLayer> $patterns
|
||||
* @return $this
|
||||
|
@ -62,7 +62,7 @@ class Block{
|
||||
protected ?array $collisionBoxes = null;
|
||||
|
||||
/**
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){
|
||||
|
@ -968,7 +968,7 @@ class BlockFactory{
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param bool $override Whether to override existing registrations
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
|
@ -135,7 +135,7 @@ class Banner extends Spawnable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
*
|
||||
* @phpstan-param list<BannerPatternLayer> $patterns
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\command;
|
||||
interface CommandExecutor{
|
||||
|
||||
/**
|
||||
* @param string[] $args
|
||||
* @param string[] $args
|
||||
*/
|
||||
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool;
|
||||
|
||||
|
@ -72,6 +72,11 @@ class GamemodeCommand extends VanillaCommand{
|
||||
throw new InvalidCommandSyntaxException();
|
||||
}
|
||||
|
||||
if($target->getGamemode()->equals($gameMode)){
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_failure($target->getName()));
|
||||
return true;
|
||||
}
|
||||
|
||||
$target->setGamemode($gameMode);
|
||||
if(!$gameMode->equals($target->getGamemode())){
|
||||
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_failure($target->getName()));
|
||||
|
@ -201,7 +201,7 @@ class CraftingManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] $outputs
|
||||
* @param Item[] $outputs
|
||||
*/
|
||||
public function matchRecipe(CraftingGrid $grid, array $outputs) : ?CraftingRecipe{
|
||||
//TODO: try to match special recipes before anything else (first they need to be implemented!)
|
||||
|
@ -46,15 +46,15 @@ class ShapedRecipe implements CraftingRecipe{
|
||||
/**
|
||||
* Constructs a ShapedRecipe instance.
|
||||
*
|
||||
* @param string[] $shape <br>
|
||||
* Array of 1, 2, or 3 strings representing the rows of the recipe.
|
||||
* This accepts an array of 1, 2 or 3 strings. Each string should be of the same length and must be at most 3
|
||||
* characters long. Each character represents a unique type of ingredient. Spaces are interpreted as air.
|
||||
* @param string[] $shape <br>
|
||||
* Array of 1, 2, or 3 strings representing the rows of the recipe.
|
||||
* This accepts an array of 1, 2 or 3 strings. Each string should be of the same length and must be at most 3
|
||||
* characters long. Each character represents a unique type of ingredient. Spaces are interpreted as air.
|
||||
* @param Item[] $ingredients <br>
|
||||
* Char => Item map of items to be set into the shape.
|
||||
* This accepts an array of Items, indexed by character. Every unique character (except space) in the shape
|
||||
* array MUST have a corresponding item in this list. Space character is automatically treated as air.
|
||||
* @param Item[] $results List of items that this recipe produces when crafted.
|
||||
* Char => Item map of items to be set into the shape.
|
||||
* This accepts an array of Items, indexed by character. Every unique character (except space) in the shape
|
||||
* array MUST have a corresponding item in this list. Space character is automatically treated as air.
|
||||
* @param Item[] $results List of items that this recipe produces when crafted.
|
||||
*
|
||||
* Note: Recipes **do not** need to be square. Do NOT add padding for empty rows/columns.
|
||||
*/
|
||||
|
@ -36,7 +36,8 @@ class ShapelessRecipe implements CraftingRecipe{
|
||||
|
||||
/**
|
||||
* @param Item[] $ingredients No more than 9 total. This applies to sum of item stack counts, not count of array.
|
||||
* @param Item[] $results List of result items created by this recipe.
|
||||
* @param Item[] $results List of result items created by this recipe.
|
||||
*
|
||||
* TODO: we'll want to make the type parameter mandatory in PM5
|
||||
*/
|
||||
public function __construct(array $ingredients, array $results, ?ShapelessRecipeType $type = null){
|
||||
|
@ -33,13 +33,13 @@ final class PotionTypeIdMap{
|
||||
* @var PotionType[]
|
||||
* @phpstan-var array<int, PotionType>
|
||||
*/
|
||||
private array $idToEnum;
|
||||
private array $idToEnum = [];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private array $enumToId;
|
||||
private array $enumToId = [];
|
||||
|
||||
private function __construct(){
|
||||
$this->register(PotionTypeIds::WATER, PotionType::WATER());
|
||||
|
@ -1598,7 +1598,7 @@ abstract class Entity{
|
||||
|
||||
/**
|
||||
* @param Player[]|null $targets
|
||||
* @param MetadataProperty[] $data Properly formatted entity data, defaults to everything
|
||||
* @param MetadataProperty[] $data Properly formatted entity data, defaults to everything
|
||||
*
|
||||
* @phpstan-param array<int, MetadataProperty> $data
|
||||
*/
|
||||
|
@ -35,9 +35,9 @@ class Effect{
|
||||
use NotSerializable;
|
||||
|
||||
/**
|
||||
* @param Translatable|string $name Translation key used for effect name
|
||||
* @param Color $color Color of bubbles given by this effect
|
||||
* @param bool $bad Whether the effect is harmful
|
||||
* @param Translatable|string $name Translation key used for effect name
|
||||
* @param Color $color Color of bubbles given by this effect
|
||||
* @param bool $bad Whether the effect is harmful
|
||||
* @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles)
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -36,7 +36,7 @@ class EffectInstance{
|
||||
private Color $color;
|
||||
|
||||
/**
|
||||
* @param int|null $duration Passing null will use the effect type's default duration
|
||||
* @param int|null $duration Passing null will use the effect type's default duration
|
||||
*/
|
||||
public function __construct(Effect $effectType, ?int $duration = null, int $amplifier = 0, bool $visible = true, bool $ambient = false, ?Color $overrideColor = null){
|
||||
$this->effectType = $effectType;
|
||||
|
@ -31,6 +31,10 @@ class HandlerList{
|
||||
/** @var RegisteredListener[][] */
|
||||
private array $handlerSlots = [];
|
||||
|
||||
/**
|
||||
* @phpstan-template TEvent of Event
|
||||
* @phpstan-param class-string<TEvent> $class
|
||||
*/
|
||||
public function __construct(
|
||||
private string $class,
|
||||
private ?HandlerList $parentList
|
||||
|
@ -52,7 +52,7 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
|
||||
|
||||
/**
|
||||
* @param Block[] $blocks
|
||||
* @param float $yield 0-100
|
||||
* @param float $yield 0-100
|
||||
*/
|
||||
public function __construct(Entity $entity, Position $position, array $blocks, float $yield){
|
||||
$this->entity = $entity;
|
||||
|
@ -35,8 +35,8 @@ class CraftItemEvent extends Event implements Cancellable{
|
||||
use CancellableTrait;
|
||||
|
||||
/**
|
||||
* @param Item[] $inputs
|
||||
* @param Item[] $outputs
|
||||
* @param Item[] $inputs
|
||||
* @param Item[] $outputs
|
||||
*/
|
||||
public function __construct(
|
||||
private CraftingTransaction $transaction,
|
||||
|
@ -34,7 +34,7 @@ interface Form extends \JsonSerializable{
|
||||
/**
|
||||
* Handles a form response from a player.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param mixed $data
|
||||
*
|
||||
* @throws FormValidationException if the data could not be processed
|
||||
*/
|
||||
|
@ -75,7 +75,7 @@ class Banner extends ItemBlockWallOrFloor{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
* @param BannerPatternLayer[] $patterns
|
||||
*
|
||||
* @phpstan-param list<BannerPatternLayer> $patterns
|
||||
*
|
||||
|
@ -121,7 +121,7 @@ abstract class Durable extends Item{
|
||||
* Returns whether the item is broken.
|
||||
*/
|
||||
public function isBroken() : bool{
|
||||
return $this->damage >= $this->getMaxDurability();
|
||||
return $this->damage >= $this->getMaxDurability() || $this->isNull();
|
||||
}
|
||||
|
||||
protected function deserializeCompoundTag(CompoundTag $tag) : void{
|
||||
|
@ -564,7 +564,7 @@ class Item implements \JsonSerializable{
|
||||
/**
|
||||
* Compares an Item to this Item and check if they match.
|
||||
*
|
||||
* @param bool $checkDamage Whether to verify that the damage values match.
|
||||
* @param bool $checkDamage Whether to verify that the damage values match.
|
||||
* @param bool $checkCompound Whether to verify that the items' NBT match.
|
||||
*/
|
||||
final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{
|
||||
|
@ -35,7 +35,7 @@ interface AdvancedNetworkInterface extends NetworkInterface{
|
||||
/**
|
||||
* Prevents packets received from the IP address getting processed for the given timeout.
|
||||
*
|
||||
* @param int $timeout Seconds
|
||||
* @param int $timeout Seconds
|
||||
*/
|
||||
public function blockAddress(string $address, int $timeout = 300) : void;
|
||||
|
||||
|
@ -80,6 +80,10 @@ class Network{
|
||||
return $this->sessionManager->getSessionCount();
|
||||
}
|
||||
|
||||
public function getValidConnectionCount() : int{
|
||||
return $this->sessionManager->getValidSessionCount();
|
||||
}
|
||||
|
||||
public function tick() : void{
|
||||
foreach($this->interfaces as $interface){
|
||||
$interface->tick();
|
||||
|
@ -32,12 +32,25 @@ class NetworkSessionManager{
|
||||
/** @var NetworkSession[] */
|
||||
private array $sessions = [];
|
||||
|
||||
/** @var NetworkSession[] */
|
||||
private array $pendingLoginSessions = [];
|
||||
|
||||
/**
|
||||
* Adds a network session to the manager. This should only be called on session creation.
|
||||
*/
|
||||
public function add(NetworkSession $session) : void{
|
||||
$idx = spl_object_id($session);
|
||||
$this->sessions[$idx] = $session;
|
||||
$this->pendingLoginSessions[$idx] = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the session as having sent a login request. After this point, they are counted towards the total player
|
||||
* count.
|
||||
*/
|
||||
public function markLoginReceived(NetworkSession $session) : void{
|
||||
$idx = spl_object_id($session);
|
||||
unset($this->pendingLoginSessions[$idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,15 +60,24 @@ class NetworkSessionManager{
|
||||
public function remove(NetworkSession $session) : void{
|
||||
$idx = spl_object_id($session);
|
||||
unset($this->sessions[$idx]);
|
||||
unset($this->pendingLoginSessions[$idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of known connected sessions.
|
||||
* Returns the number of known connected sessions, including sessions which have not yet sent a login request.
|
||||
*/
|
||||
public function getSessionCount() : int{
|
||||
return count($this->sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of connected sessions which have either sent a login request, or have already completed the
|
||||
* login sequence.
|
||||
*/
|
||||
public function getValidSessionCount() : int{
|
||||
return count($this->sessions) - count($this->pendingLoginSessions);
|
||||
}
|
||||
|
||||
/** @return NetworkSession[] */
|
||||
public function getSessions() : array{ return $this->sessions; }
|
||||
|
||||
|
@ -191,8 +191,10 @@ class InventoryManager{
|
||||
*/
|
||||
public function addPredictedSlotChanges(array $networkInventoryActions) : void{
|
||||
foreach($networkInventoryActions as $action){
|
||||
if($action->sourceType === NetworkInventoryAction::SOURCE_CONTAINER && isset($this->windowMap[$action->windowId])){
|
||||
//this won't cover stuff like crafting grid due to too much magic
|
||||
if($action->sourceType === NetworkInventoryAction::SOURCE_CONTAINER && (
|
||||
isset($this->windowMap[$action->windowId]) ||
|
||||
($action->windowId === ContainerIds::UI && isset($this->complexSlotToWindowMap[$action->inventorySlot]))
|
||||
)){
|
||||
try{
|
||||
$item = TypeConverter::getInstance()->netItemStackToCore($action->newItem->getItemStack());
|
||||
}catch(TypeConversionException $e){
|
||||
|
@ -229,6 +229,7 @@ class NetworkSession{
|
||||
$this->info = $info;
|
||||
$this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET);
|
||||
$this->logger->setPrefix($this->getLogPrefix());
|
||||
$this->manager->markLoginReceived($this);
|
||||
},
|
||||
function(bool $isAuthenticated, bool $authRequired, ?string $error, ?string $clientPubKey) : void{
|
||||
$this->setAuthenticationStatus($isAuthenticated, $authRequired, $error, $clientPubKey);
|
||||
@ -365,7 +366,7 @@ class NetworkSession{
|
||||
}
|
||||
|
||||
try{
|
||||
foreach((new PacketBatch($decompressed))->getPackets($this->packetPool, $this->packetSerializerContext, 500) as [$packet, $buffer]){
|
||||
foreach((new PacketBatch($decompressed))->getPackets($this->packetPool, $this->packetSerializerContext, 1300) as [$packet, $buffer]){
|
||||
if($packet === null){
|
||||
$this->logger->debug("Unknown packet: " . base64_encode($buffer));
|
||||
throw new PacketHandlingException("Unknown packet received");
|
||||
|
@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
interface PacketBroadcaster{
|
||||
|
||||
/**
|
||||
* @param NetworkSession[] $recipients
|
||||
* @param NetworkSession[] $recipients
|
||||
* @param ClientboundPacket[] $packets
|
||||
*/
|
||||
public function broadcastPackets(array $recipients, array $packets) : void;
|
||||
|
@ -118,7 +118,7 @@ final class ItemTranslator{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $simpleMappings
|
||||
* @param int[] $simpleMappings
|
||||
* @param int[][] $complexMappings
|
||||
* @phpstan-param array<string, int> $simpleMappings
|
||||
* @phpstan-param array<string, array<int, int>> $complexMappings
|
||||
|
@ -34,6 +34,7 @@ use function openssl_digest;
|
||||
use function openssl_error_string;
|
||||
use function openssl_pkey_derive;
|
||||
use function str_pad;
|
||||
use const STR_PAD_LEFT;
|
||||
|
||||
final class EncryptionUtils{
|
||||
|
||||
|
@ -254,6 +254,9 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
$useItemTransaction = $packet->getItemInteractionData();
|
||||
if($useItemTransaction !== null){
|
||||
if(count($useItemTransaction->getTransactionData()->getActions()) > 100){
|
||||
throw new PacketHandlingException("Too many actions in item use transaction");
|
||||
}
|
||||
if(!$this->handleUseItemTransaction($useItemTransaction->getTransactionData())){
|
||||
$packetHandled = false;
|
||||
$this->session->getLogger()->debug("Unhandled transaction in PlayerAuthInputPacket (type " . $useItemTransaction->getTransactionData()->getActionType() . ")");
|
||||
@ -264,6 +267,9 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
$blockActions = $packet->getBlockActions();
|
||||
if($blockActions !== null){
|
||||
if(count($blockActions) > 100){
|
||||
throw new PacketHandlingException("Too many block actions in PlayerAuthInputPacket");
|
||||
}
|
||||
foreach($blockActions as $k => $blockAction){
|
||||
$actionHandled = false;
|
||||
if($blockAction instanceof PlayerBlockActionStopBreak){
|
||||
@ -310,6 +316,12 @@ class InGamePacketHandler extends PacketHandler{
|
||||
public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{
|
||||
$result = true;
|
||||
|
||||
if(count($packet->trData->getActions()) > 100){
|
||||
throw new PacketHandlingException("Too many actions in inventory transaction");
|
||||
}
|
||||
|
||||
$this->inventoryManager->addPredictedSlotChanges($packet->trData->getActions());
|
||||
|
||||
if($packet->trData instanceof NormalTransactionData){
|
||||
$result = $this->handleNormalTransaction($packet->trData);
|
||||
}elseif($packet->trData instanceof MismatchTransactionData){
|
||||
@ -324,9 +336,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
$result = $this->handleReleaseItemTransaction($packet->trData);
|
||||
}
|
||||
|
||||
if(!$result){
|
||||
$this->inventoryManager->syncAll();
|
||||
}else{
|
||||
if($this->craftingTransaction === null){ //don't sync if we're waiting to complete a crafting transaction
|
||||
$this->inventoryManager->syncMismatchedPredictedSlotChanges();
|
||||
}
|
||||
return $result;
|
||||
@ -381,15 +391,9 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
$this->player->setUsingItem(false);
|
||||
try{
|
||||
$this->inventoryManager->onTransactionStart($this->craftingTransaction);
|
||||
$this->craftingTransaction->execute();
|
||||
}catch(TransactionException $e){
|
||||
$this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage());
|
||||
|
||||
//TODO: only sync slots that the client tried to change
|
||||
foreach($this->craftingTransaction->getInventories() as $inventory){
|
||||
$this->inventoryManager->syncContents($inventory);
|
||||
}
|
||||
return false;
|
||||
}finally{
|
||||
$this->craftingTransaction = null;
|
||||
@ -409,18 +413,12 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
$this->player->setUsingItem(false);
|
||||
$transaction = new InventoryTransaction($this->player, $actions);
|
||||
$this->inventoryManager->onTransactionStart($transaction);
|
||||
try{
|
||||
$transaction->execute();
|
||||
}catch(TransactionException $e){
|
||||
$logger = $this->session->getLogger();
|
||||
$logger->debug("Failed to execute inventory transaction: " . $e->getMessage());
|
||||
$logger->debug("Actions: " . json_encode($data->getActions()));
|
||||
|
||||
foreach($transaction->getInventories() as $inventory){
|
||||
$this->inventoryManager->syncContents($inventory);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -430,7 +428,6 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
private function handleUseItemTransaction(UseItemTransactionData $data) : bool{
|
||||
$this->player->selectHotbarSlot($data->getHotbarSlot());
|
||||
$this->inventoryManager->addPredictedSlotChanges($data->getActions());
|
||||
|
||||
switch($data->getActionType()){
|
||||
case UseItemTransactionData::ACTION_CLICK_BLOCK:
|
||||
@ -516,9 +513,7 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
$this->player->selectHotbarSlot($data->getHotbarSlot());
|
||||
$this->inventoryManager->addPredictedSlotChanges($data->getActions());
|
||||
|
||||
//TODO: use transactiondata for rollbacks here
|
||||
switch($data->getActionType()){
|
||||
case UseItemOnEntityTransactionData::ACTION_INTERACT:
|
||||
$this->player->interactEntity($target, $data->getClickPosition());
|
||||
@ -533,15 +528,10 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{
|
||||
$this->player->selectHotbarSlot($data->getHotbarSlot());
|
||||
$this->inventoryManager->addPredictedSlotChanges($data->getActions());
|
||||
|
||||
//TODO: use transactiondata for rollbacks here (resending entire inventory is very wasteful)
|
||||
switch($data->getActionType()){
|
||||
case ReleaseItemTransactionData::ACTION_RELEASE:
|
||||
if(!$this->player->releaseHeldItem()){
|
||||
$this->inventoryManager->syncContents($this->player->getInventory());
|
||||
}
|
||||
return true;
|
||||
if($data->getActionType() == ReleaseItemTransactionData::ACTION_RELEASE){
|
||||
$this->player->releaseHeldItem();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -123,7 +123,7 @@ class LoginPacketHandler extends PacketHandler{
|
||||
$this->session->getPort(),
|
||||
$this->server->requiresAuthentication()
|
||||
);
|
||||
if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){
|
||||
if($this->server->getNetwork()->getValidConnectionCount() > $this->server->getMaxPlayers()){
|
||||
$ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL);
|
||||
}
|
||||
if(!$this->server->isWhitelisted($playerInfo->getUsername())){
|
||||
|
@ -52,6 +52,7 @@ use function mt_rand;
|
||||
use function random_bytes;
|
||||
use function rtrim;
|
||||
use function substr;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
|
||||
/**
|
||||
|
@ -40,6 +40,7 @@ use function strlen;
|
||||
use function time;
|
||||
use function trim;
|
||||
use const AF_INET;
|
||||
use const AF_INET6;
|
||||
use const IPPROTO_IPV6;
|
||||
use const IPV6_V6ONLY;
|
||||
use const PHP_INT_MAX;
|
||||
|
@ -73,6 +73,12 @@ use function sprintf;
|
||||
use function strlen;
|
||||
use function trim;
|
||||
use const AF_INET;
|
||||
use const PREG_BACKTRACK_LIMIT_ERROR;
|
||||
use const PREG_BAD_UTF8_ERROR;
|
||||
use const PREG_BAD_UTF8_OFFSET_ERROR;
|
||||
use const PREG_INTERNAL_ERROR;
|
||||
use const PREG_JIT_STACKLIMIT_ERROR;
|
||||
use const PREG_RECURSION_LIMIT_ERROR;
|
||||
use const SO_RCVTIMEO;
|
||||
use const SOCK_DGRAM;
|
||||
use const SOCKET_ETIMEDOUT;
|
||||
|
@ -1390,7 +1390,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
/**
|
||||
* Returns whether the player can interact with the specified position. This checks distance and direction.
|
||||
*
|
||||
* @param float $maxDiff defaults to half of the 3D diagonal width of a block
|
||||
* @param float $maxDiff defaults to half of the 3D diagonal width of a block
|
||||
*/
|
||||
public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{
|
||||
$eyePos = $this->getEyePos();
|
||||
@ -1916,9 +1916,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
/**
|
||||
* Adds a title text to the user's screen, with an optional subtitle.
|
||||
*
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
* @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used.
|
||||
* @param int $stay Duration in ticks to stay on screen for
|
||||
* @param int $fadeOut Duration in ticks for fade-out.
|
||||
*/
|
||||
public function sendTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1) : void{
|
||||
$this->setTitleDuration($fadeIn, $stay, $fadeOut);
|
||||
@ -1959,8 +1959,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
/**
|
||||
* Sets the title duration.
|
||||
*
|
||||
* @param int $fadeIn Title fade-in time in ticks.
|
||||
* @param int $stay Title stay time in ticks.
|
||||
* @param int $fadeIn Title fade-in time in ticks.
|
||||
* @param int $stay Title stay time in ticks.
|
||||
* @param int $fadeOut Title fade-out time in ticks.
|
||||
*/
|
||||
public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut) : void{
|
||||
@ -2061,7 +2061,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
* Transfers a player to another server.
|
||||
*
|
||||
* @param string $address The IP address or hostname of the destination server
|
||||
* @param int $port The destination port, defaults to 19132
|
||||
* @param int $port The destination port, defaults to 19132
|
||||
* @param string $message Message to show in the console when closing the player
|
||||
*
|
||||
* @return bool if transfer was successful.
|
||||
@ -2105,7 +2105,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
*
|
||||
* Note for internals developers: Do not call this from network sessions. It will cause a feedback loop.
|
||||
*
|
||||
* @param string $reason Shown to the player, usually this will appear on their disconnect screen.
|
||||
* @param string $reason Shown to the player, usually this will appear on their disconnect screen.
|
||||
* @param Translatable|string|null $quitMessage Message to broadcast to online players (null will use default)
|
||||
*/
|
||||
public function disconnect(string $reason, Translatable|string|null $quitMessage = null) : void{
|
||||
@ -2121,7 +2121,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
* @internal
|
||||
* This method executes post-disconnect actions and cleanups.
|
||||
*
|
||||
* @param string $reason Shown to the player, usually this will appear on their disconnect screen.
|
||||
* @param string $reason Shown to the player, usually this will appear on their disconnect screen.
|
||||
* @param Translatable|string|null $quitMessage Message to broadcast to online players (null will use default)
|
||||
*/
|
||||
public function onPostDisconnect(string $reason, Translatable|string|null $quitMessage) : void{
|
||||
|
@ -45,6 +45,7 @@ use function stream_copy_to_stream;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function trim;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
abstract class PluginBase implements Plugin, CommandExecutor{
|
||||
private bool $isEnabled = false;
|
||||
@ -201,7 +202,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $args
|
||||
* @param string[] $args
|
||||
*/
|
||||
public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool{
|
||||
return false;
|
||||
|
@ -57,7 +57,7 @@ interface ResourcePack{
|
||||
* Note that resource packs must **always** be in zip archive format for sending.
|
||||
* A folder resource loader may need to perform on-the-fly compression for this purpose.
|
||||
*
|
||||
* @param int $start Offset to start reading the chunk from
|
||||
* @param int $start Offset to start reading the chunk from
|
||||
* @param int $length Maximum length of data to return.
|
||||
*
|
||||
* @return string byte-array
|
||||
|
@ -58,7 +58,7 @@ class ResourcePackManager{
|
||||
private array $encryptionKeys = [];
|
||||
|
||||
/**
|
||||
* @param string $path Path to resource-packs directory.
|
||||
* @param string $path Path to resource-packs directory.
|
||||
*/
|
||||
public function __construct(string $path, \Logger $logger){
|
||||
$this->path = $path;
|
||||
|
@ -187,7 +187,7 @@ abstract class AsyncTask extends \Threaded{
|
||||
* {@link AsyncTask::onCompletion} is called.
|
||||
*
|
||||
* @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed
|
||||
* and then unserialize()'ed, as if it has been cloned.
|
||||
* and then unserialize()'ed, as if it has been cloned.
|
||||
*/
|
||||
public function onProgressUpdate($progress) : void{
|
||||
|
||||
@ -215,7 +215,7 @@ abstract class AsyncTask extends \Threaded{
|
||||
* Objects stored in this storage can be retrieved using fetchLocal() on the same thread that this method was called
|
||||
* from.
|
||||
*
|
||||
* @param mixed $complexData the data to store
|
||||
* @param mixed $complexData the data to store
|
||||
*/
|
||||
protected function storeLocal(string $key, $complexData) : void{
|
||||
if(self::$threadLocalStorage === null){
|
||||
|
@ -77,7 +77,7 @@ class AsyncWorker extends Worker{
|
||||
* Saves mixed data into the worker's thread-local object store. This can be used to store objects which you
|
||||
* want to use on this worker thread from multiple AsyncTasks.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function saveToThreadStore(string $identifier, $value) : void{
|
||||
if(\Thread::getCurrentThread() !== $this){
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\scheduler;
|
||||
final class BulkCurlTaskOperation{
|
||||
/**
|
||||
* @param string[] $extraHeaders
|
||||
* @param mixed[] $extraOpts
|
||||
* @param mixed[] $extraOpts
|
||||
* @phpstan-param list<string> $extraHeaders
|
||||
* @phpstan-param array<int, mixed> $extraOpts
|
||||
*/
|
||||
|
@ -29,6 +29,7 @@ use pocketmine\lang\Translatable;
|
||||
use pocketmine\permission\PermissibleBase;
|
||||
use pocketmine\permission\PermissibleDelegateTrait;
|
||||
use pocketmine\Server;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
/**
|
||||
* Forwards any messages it receives via sendMessage() to the given logger. Used for forwarding chat messages and
|
||||
|
@ -23,6 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
/**
|
||||
* This trait offers the same functionality as RegistryTrait, but also clones any returned objects to prevent outside
|
||||
* modification.
|
||||
*/
|
||||
trait CloningRegistryTrait{
|
||||
use RegistryTrait;
|
||||
|
||||
|
@ -55,6 +55,7 @@ use const CASE_LOWER;
|
||||
use const JSON_BIGINT_AS_STRING;
|
||||
use const JSON_PRETTY_PRINT;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
use const YAML_UTF8_ENCODING;
|
||||
|
||||
/**
|
||||
* Config Class for simple config manipulation of multiple formats.
|
||||
@ -108,8 +109,8 @@ class Config{
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $file Path of the file to be loaded
|
||||
* @param int $type Config type to load, -1 by default (detect)
|
||||
* @param string $file Path of the file to be loaded
|
||||
* @param int $type Config type to load, -1 by default (detect)
|
||||
* @param mixed[] $default Array with the default values that will be written to the file if it did not exist
|
||||
* @phpstan-param array<string, mixed> $default
|
||||
*/
|
||||
@ -493,7 +494,7 @@ class Config{
|
||||
|
||||
/**
|
||||
* @param mixed[] $default
|
||||
* @param mixed[] $data reference parameter
|
||||
* @param mixed[] $data reference parameter
|
||||
* @phpstan-param array<string, mixed> $default
|
||||
* @phpstan-param array<string, mixed> $data
|
||||
* @phpstan-param-out array<string, mixed> $data
|
||||
|
@ -23,6 +23,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
/**
|
||||
* This trait allows a class to simulate a Java-style enum. Members are exposed as static methods and handled via
|
||||
* __callStatic().
|
||||
*
|
||||
* Classes using this trait need to include \@method tags in their class docblock for every enum member.
|
||||
* Alternatively, just put \@generate-registry-docblock in the docblock and run tools/generate-registry-annotations.php
|
||||
*/
|
||||
trait EnumTrait{
|
||||
use RegistryTrait;
|
||||
use NotCloneable;
|
||||
|
@ -187,9 +187,10 @@ final class Filesystem{
|
||||
* @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied)
|
||||
*/
|
||||
public static function createLockFile(string $lockFilePath) : ?int{
|
||||
$resource = fopen($lockFilePath, "a+b");
|
||||
if($resource === false){
|
||||
throw new \InvalidArgumentException("Invalid lock file path or read/write permissions denied");
|
||||
try{
|
||||
$resource = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen($lockFilePath, "a+b"));
|
||||
}catch(\ErrorException $e){
|
||||
throw new \InvalidArgumentException("Failed to open lock file: " . $e->getMessage(), 0, $e);
|
||||
}
|
||||
if(!flock($resource, LOCK_EX | LOCK_NB)){
|
||||
//wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the
|
||||
|
@ -36,7 +36,7 @@ final class Git{
|
||||
/**
|
||||
* Returns the git hash of the currently checked out head of the given repository, or null on failure.
|
||||
*
|
||||
* @param bool $dirty reference parameter, set to whether the repo has local changes
|
||||
* @param bool $dirty reference parameter, set to whether the repo has local changes
|
||||
*/
|
||||
public static function getRepositoryState(string $dir, bool &$dirty) : ?string{
|
||||
if(Process::execute("git -C \"$dir\" rev-parse HEAD", $out) === 0 && $out !== false && strlen($out = trim($out)) === 40){
|
||||
|
@ -141,9 +141,9 @@ class Internet{
|
||||
*
|
||||
* @phpstan-template TErrorVar of mixed
|
||||
*
|
||||
* @param int $timeout default 10
|
||||
* @param int $timeout default 10
|
||||
* @param string[] $extraHeaders
|
||||
* @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation.
|
||||
* @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation.
|
||||
* @phpstan-param list<string> $extraHeaders
|
||||
* @phpstan-param TErrorVar $err
|
||||
* @phpstan-param-out TErrorVar|string $err
|
||||
@ -165,7 +165,7 @@ class Internet{
|
||||
*
|
||||
* @param string[]|string $args
|
||||
* @param string[] $extraHeaders
|
||||
* @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occurred during the operation.
|
||||
* @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occurred during the operation.
|
||||
* @phpstan-param string|array<string, string> $args
|
||||
* @phpstan-param list<string> $extraHeaders
|
||||
* @phpstan-param TErrorVar $err
|
||||
@ -187,7 +187,7 @@ class Internet{
|
||||
* General cURL shorthand function.
|
||||
* NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread.
|
||||
*
|
||||
* @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms.
|
||||
* @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms.
|
||||
* @param string[] $extraHeaders extra headers to send as a plain string array
|
||||
* @param array $extraOpts extra CURLOPT_* to set as an [opt => value] map
|
||||
* @param \Closure|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle.
|
||||
|
@ -150,8 +150,8 @@ final class Process{
|
||||
|
||||
/**
|
||||
* @param string $command Command to execute
|
||||
* @param string|null $stdout Reference parameter to write stdout to
|
||||
* @param string|null $stderr Reference parameter to write stderr to
|
||||
* @param string|null $stdout Reference parameter to write stdout to
|
||||
* @param string|null $stderr Reference parameter to write stderr to
|
||||
* @phpstan-param-out string $stdout
|
||||
* @phpstan-param-out string $stderr
|
||||
*
|
||||
|
@ -115,7 +115,7 @@ class Random{
|
||||
* Returns a random integer between $start and $end
|
||||
*
|
||||
* @param int $start default 0
|
||||
* @param int $end default 0x7fffffff
|
||||
* @param int $end default 0x7fffffff
|
||||
*/
|
||||
public function nextRange(int $start = 0, int $end = 0x7fffffff) : int{
|
||||
return $start + ($this->nextInt() % ($end + 1 - $start));
|
||||
|
@ -28,6 +28,13 @@ use function count;
|
||||
use function mb_strtoupper;
|
||||
use function preg_match;
|
||||
|
||||
/**
|
||||
* This trait allows a class to simulate object class constants, since PHP doesn't currently support this.
|
||||
* These faux constants are exposed in static class methods, which are handled using __callStatic().
|
||||
*
|
||||
* Classes using this trait need to include \@method tags in their class docblock for every faux constant.
|
||||
* Alternatively, just put \@generate-registry-docblock in the docblock and run tools/generate-registry-annotations.php
|
||||
*/
|
||||
trait RegistryTrait{
|
||||
/**
|
||||
* @var object[]
|
||||
|
@ -539,7 +539,7 @@ final class Utils{
|
||||
* incompatible.
|
||||
*
|
||||
* @param callable|CallbackType $signature Dummy callable with the required parameters and return type
|
||||
* @param callable $subject Callable to check the signature of
|
||||
* @param callable $subject Callable to check the signature of
|
||||
* @phpstan-param anyCallable|CallbackType $signature
|
||||
* @phpstan-param anyCallable $subject
|
||||
*
|
||||
|
@ -643,7 +643,7 @@ class World implements ChunkManager{
|
||||
* Returns a list of players who are in the given filter and also using the chunk containing the target position.
|
||||
* Used for broadcasting sounds and particles with specific targets.
|
||||
*
|
||||
* @param Player[] $allowed
|
||||
* @param Player[] $allowed
|
||||
* @phpstan-param list<Player> $allowed
|
||||
*
|
||||
* @return array<int, Player>
|
||||
@ -1222,7 +1222,8 @@ class World implements ChunkManager{
|
||||
private function tickChunk(int $chunkX, int $chunkZ) : void{
|
||||
$chunk = $this->getChunk($chunkX, $chunkZ);
|
||||
if($chunk === null){
|
||||
throw new \InvalidArgumentException("Chunk is not loaded");
|
||||
//the chunk may have been unloaded during a previous chunk's update (e.g. during BlockGrowEvent)
|
||||
return;
|
||||
}
|
||||
foreach($this->getChunkEntities($chunkX, $chunkZ) as $entity){
|
||||
$entity->onRandomUpdate();
|
||||
@ -1634,8 +1635,8 @@ class World implements ChunkManager{
|
||||
* Note: If you're using this for performance-sensitive code, and you're guaranteed to be supplying ints in the
|
||||
* specified vector, consider using {@link getBlockAt} instead for better performance.
|
||||
*
|
||||
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
|
||||
* @param bool $addToCache Whether to cache the block object created by this method call.
|
||||
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
|
||||
* @param bool $addToCache Whether to cache the block object created by this method call.
|
||||
*/
|
||||
public function getBlock(Vector3 $pos, bool $cached = true, bool $addToCache = true) : Block{
|
||||
return $this->getBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $cached, $addToCache);
|
||||
@ -1647,7 +1648,7 @@ class World implements ChunkManager{
|
||||
* Note for plugin developers: If you are using this method a lot (thousands of times for many positions for
|
||||
* example), you may want to set addToCache to false to avoid using excessive amounts of memory.
|
||||
*
|
||||
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
|
||||
* @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate)
|
||||
* @param bool $addToCache Whether to cache the block object created by this method call.
|
||||
*/
|
||||
public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{
|
||||
@ -1794,7 +1795,7 @@ class World implements ChunkManager{
|
||||
* Tries to break a block using a item, including Player time checks if available
|
||||
* It'll try to lower the durability if Item is a tool, and set it to Air if broken.
|
||||
*
|
||||
* @param Item $item reference parameter (if null, can break anything)
|
||||
* @param Item $item reference parameter (if null, can break anything)
|
||||
* @phpstan-param-out Item $item
|
||||
*/
|
||||
public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{
|
||||
@ -1896,8 +1897,8 @@ class World implements ChunkManager{
|
||||
/**
|
||||
* Uses a item on a position and face, placing it or activating the block
|
||||
*
|
||||
* @param Player|null $player default null
|
||||
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
|
||||
* @param Player|null $player default null
|
||||
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
|
||||
*/
|
||||
public function useItemOn(Vector3 $vector, Item &$item, int $face, ?Vector3 $clickVector = null, ?Player $player = null, bool $playSound = false) : bool{
|
||||
$blockClicked = $this->getBlock($vector);
|
||||
@ -2092,8 +2093,8 @@ class World implements ChunkManager{
|
||||
/**
|
||||
* Returns the closest Entity to the specified position, within the given radius.
|
||||
*
|
||||
* @param string $entityType Class of entity to use for instanceof
|
||||
* @param bool $includeDead Whether to include entitites which are dead
|
||||
* @param string $entityType Class of entity to use for instanceof
|
||||
* @param bool $includeDead Whether to include entitites which are dead
|
||||
* @phpstan-template TEntity of Entity
|
||||
* @phpstan-param class-string<TEntity> $entityType
|
||||
*
|
||||
|
@ -166,7 +166,7 @@ class WorldManager{
|
||||
/**
|
||||
* Loads a world from the data directory
|
||||
*
|
||||
* @param bool $autoUpgrade Converts worlds to the default format if the world's format is not writable / deprecated
|
||||
* @param bool $autoUpgrade Converts worlds to the default format if the world's format is not writable / deprecated
|
||||
*
|
||||
* @throws WorldException
|
||||
*/
|
||||
|
@ -164,8 +164,8 @@ class Chunk{
|
||||
/**
|
||||
* Sets the biome ID at the specified X/Z chunk block coordinates
|
||||
*
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
* @param int $biomeId 0-255
|
||||
*/
|
||||
public function setBiomeId(int $x, int $z, int $biomeId) : void{
|
||||
|
@ -504,7 +504,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CompoundTag[] $targets
|
||||
* @param CompoundTag[] $targets
|
||||
*/
|
||||
private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{
|
||||
if(count($targets) > 0){
|
||||
|
@ -38,7 +38,7 @@ use function preg_match_all;
|
||||
final class FlatGeneratorOptions{
|
||||
|
||||
/**
|
||||
* @param int[] $structure
|
||||
* @param int[] $structure
|
||||
* @param mixed[] $extraOptions
|
||||
* @phpstan-param array<int, int> $structure
|
||||
* @phpstan-param array<string, array<string, string>|true> $extraOptions
|
||||
|
@ -58,10 +58,10 @@ final class GeneratorManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator
|
||||
* @param string $name Alias for this generator type that can be written in configs
|
||||
* @param \Closure $presetValidator Callback to validate generator options for new worlds
|
||||
* @param bool $overwrite Whether to force overwriting any existing registered generator with the same name
|
||||
* @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator
|
||||
* @param string $name Alias for this generator type that can be written in configs
|
||||
* @param \Closure $presetValidator Callback to validate generator options for new worlds
|
||||
* @param bool $overwrite Whether to force overwriting any existing registered generator with the same name
|
||||
*
|
||||
* @phpstan-param \Closure(string) : ?InvalidGeneratorOptionsException $presetValidator
|
||||
*
|
||||
|
@ -208,8 +208,8 @@ class SkyLightUpdate extends LightUpdate{
|
||||
/**
|
||||
* Recalculates the heightmap for the block column at the specified X/Z chunk coordinates
|
||||
*
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
* @param \SplFixedArray|bool[] $directSkyLightBlockers
|
||||
* @phpstan-param \SplFixedArray<bool> $directSkyLightBlockers
|
||||
*
|
||||
|
@ -15,11 +15,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/entity/projectile/Projectile.php
|
||||
|
||||
-
|
||||
message: "#^Empty array passed to foreach\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/network/mcpe/cache/ChunkCache.php
|
||||
|
||||
-
|
||||
message: "#^Match arm comparison between 4 and 4 is always true\\.$#"
|
||||
count: 1
|
||||
@ -51,7 +46,7 @@ parameters:
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
-
|
||||
message: "#^Offset \\(int\\|string\\) on non\\-empty\\-array\\<pocketmine\\\\plugin\\\\Plugin\\> in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
message: "#^Offset \\(int\\|string\\) on array\\<pocketmine\\\\plugin\\\\Plugin\\> in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/plugin/PluginManager.php
|
||||
|
||||
@ -70,11 +65,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../../src/thread/Worker.php
|
||||
|
||||
-
|
||||
message: "#^Offset \\(int\\|string\\) on non\\-empty\\-array\\<pocketmine\\\\world\\\\World\\> in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/world/WorldManager.php
|
||||
|
||||
-
|
||||
message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#"
|
||||
count: 2
|
||||
|
@ -57,7 +57,7 @@ class StupidJsonDecodeTest extends TestCase{
|
||||
/**
|
||||
* @dataProvider stupidJsonDecodeProvider
|
||||
*
|
||||
* @param mixed $expect
|
||||
* @param mixed $expect
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
|
@ -43,6 +43,10 @@ use function rename;
|
||||
use function round;
|
||||
use function scandir;
|
||||
use function unlink;
|
||||
use const PATHINFO_EXTENSION;
|
||||
use const PHP_BINARY;
|
||||
use const SCANDIR_SORT_NONE;
|
||||
use const SORT_NUMERIC;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
|
89
tools/decode-crashdump.php
Normal file
89
tools/decode-crashdump.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\tools\decode_crashdump;
|
||||
|
||||
use function array_pop;
|
||||
use function array_slice;
|
||||
use function base64_decode;
|
||||
use function count;
|
||||
use function file;
|
||||
use function file_put_contents;
|
||||
use function fwrite;
|
||||
use function implode;
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
use function realpath;
|
||||
use function trim;
|
||||
use function zlib_decode;
|
||||
use const FILE_IGNORE_NEW_LINES;
|
||||
use const JSON_PRETTY_PRINT;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const PHP_EOL;
|
||||
use const STDERR;
|
||||
|
||||
if(count($argv) === 2){
|
||||
$input = $argv[1];
|
||||
$output = "decoded.json";
|
||||
}elseif(count($argv) === 3){
|
||||
[, $input, $output] = $argv;
|
||||
}else{
|
||||
fwrite(STDERR, "Required arguments: input file, output file" . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$lines = file($input, FILE_IGNORE_NEW_LINES);
|
||||
if($lines === false){
|
||||
fwrite(STDERR, "Unable to read file $input" . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$start = -1;
|
||||
foreach($lines as $num => $line){
|
||||
if(trim($line) === "===BEGIN CRASH DUMP==="){
|
||||
$start = $num + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($start === -1){
|
||||
fwrite(STDERR, "Crashdump encoded data not found in target file" . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$data = array_slice($lines, $start);
|
||||
array_pop($data);
|
||||
|
||||
$zlibData = base64_decode(implode("", $data), true);
|
||||
if($zlibData === false){
|
||||
fwrite(STDERR, "Invalid encoded data in crashdump" . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
$decoded = zlib_decode($zlibData);
|
||||
if($decoded === false){
|
||||
fwrite(STDERR, "Invalid compressed data in crashdump" . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file_put_contents($output, json_encode(json_decode($decoded), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
echo "Wrote decoded crashdump to " . realpath($output) . PHP_EOL;
|
@ -49,9 +49,13 @@ use function socket_strerror;
|
||||
use function strlen;
|
||||
use function time;
|
||||
use function trim;
|
||||
use const AF_INET;
|
||||
use const MSG_DONTROUTE;
|
||||
use const PHP_BINARY;
|
||||
use const PHP_INT_MAX;
|
||||
use const SOCK_DGRAM;
|
||||
use const SOL_UDP;
|
||||
use const STDIN;
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
|
Reference in New Issue
Block a user