Compare commits

...

101 Commits

Author SHA1 Message Date
fc072b05d6 tweak config defaults 2025-03-12 01:06:01 +00:00
2589fcb31d Implement rate limits by packet read ops
for now this is configured to warn only by default, until we get the parameters for it dialled in
2025-03-12 01:03:34 +00:00
8d255a6512 ... 2025-03-11 14:28:44 +00:00
41789bc67a Report debug stats for cost accounting every 10 seconds 2025-03-11 12:41:59 +00:00
afc4a3c7f1 Fixed entity position offset not being included in AddActorPacket (#6643)
this was causing TNT and falling blocks to briefly appear half a block lower than their true position, because their positions are measured from the center and not the base.
2025-03-09 02:09:53 +00:00
7af5eb3da2 crafting: validate array inputs
this makes sure wrong parameters don't show up as core errors, as seen in crash report 12373907
closes #6642
2025-03-09 01:10:12 +00:00
aad2bce9e4 readme: call out Easy tasks issues 2025-03-09 00:23:59 +00:00
50a1e59aa4 5.25.3 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/13662905668
2025-03-04 21:05:10 +00:00
e8824a36b9 Merge pull request #6645 from pmmp/explode-limit
5.25.2
2025-03-04 21:03:52 +00:00
b1e63e544f Merge branch 'stable' into explode-limit 2025-03-04 21:00:40 +00:00
9e9f8a4870 Prepare 5.25.2 release 2025-03-04 20:57:47 +00:00
d0d84d4c51 New rule: explode() limit parameter must be set 2025-03-04 20:44:01 +00:00
e3e0c14275 Bump the github-actions group with 2 updates (#6644) 2025-03-01 10:04:01 +00:00
3a2d0d77d1 Update composer dependencies 2025-02-26 17:30:20 +00:00
32b98dcbde draft-release: add a warning about bug reporting
too many people just spam on discord and expect that to somehow do something ...
2025-02-26 17:23:27 +00:00
092ea07d51 5.25.2 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/13549549222
2025-02-26 17:14:49 +00:00
706f391068 Release 5.25.1 (#6641) 2025-02-26 17:13:44 +00:00
7c654271a8 Bump phpstan/phpstan in the development-patch-updates group (#6640) 2025-02-25 13:40:11 +00:00
3df2bdb879 Fixed door facing
this was broken in 1.21.60 update.

should've known better to expect a blockstate upgrade to mean a
blockstate fix...
2025-02-24 01:04:52 +00:00
1fed9f6cb5 BlockBreakInfo: fixed confusing error message 2025-02-23 20:02:27 +00:00
3050af0bc0 ResourcePackManager: validate pack UUIDs
fixes CrashArchive ##12248760
2025-02-23 19:45:38 +00:00
77be5f8e25 Update PHPStan 2025-02-17 17:51:39 +00:00
34f801ee3c 5.25.1 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/13359320328
2025-02-16 22:18:20 +00:00
d96ef21c4d Prepare 5.25.0 release (#6631) 2025-02-16 22:16:47 +00:00
03e4b53ac4 BedrockDataFiles: added constants for folders as well as files
we probably should have it recurse too, but this is an easy win.
2025-02-16 20:57:16 +00:00
91ac64783f Bedrock 1.21.60 (#6627)
Co-authored-by: Dylan K. Taylor <dktapps@pmmp.io>
2025-02-16 20:51:53 +00:00
9402a20ee3 Update Utils::getOS() doc comment
closes #6628
2025-02-16 16:12:29 +00:00
5ef89200c6 Bump phpstan/phpstan in the development-patch-updates group (#6620) 2025-02-10 22:14:30 +00:00
39e69276a1 Bump tests/plugins/DevTools from c6dca35 to a030d39 (#6617) 2025-02-03 11:43:03 +00:00
94797e3afa Bump build/php from ae94694 to 1549433 (#6616) 2025-02-03 11:42:37 +00:00
9d6a0cc738 Update composer dependencies 2025-02-02 19:46:54 +00:00
07987890a0 Bump the github-actions group with 2 updates (#6613) 2025-02-01 13:38:25 +00:00
f60120a75e Bump the development-patch-updates group with 3 updates (#6603) 2025-01-27 10:43:28 +00:00
fc86d3a44e 5.24.1 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/12916833718
2025-01-22 20:50:42 +00:00
393d7f72a9 5.24.0
5.24.0 minor release
2025-01-22 20:49:38 +00:00
b625fee94b Prepare 5.24.0 release 2025-01-22 18:00:41 +00:00
6b606dca95 UPnP: better fix for postURL error that doesn't require behavioural breaks 2025-01-22 17:46:43 +00:00
406ddf3e53 Revert "Internet: make postURL() error reporting behaviour more predictable"
This reverts commit 97c5902ae2.
2025-01-22 17:44:23 +00:00
ec6077776a Merge branch 'minor-next' of github.com:pmmp/PocketMine-MP into minor-next 2025-01-22 16:45:49 +00:00
f7b5cd7ff3 Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12899221905
2025-01-22 01:23:49 +00:00
3453ff03fd 5.23.4 is next
Commit created by: https://github.com/pmmp/RestrictedActions/actions/runs/12898306655
2025-01-22 00:10:10 +00:00
04e63172c3 5.23.3 (#6597) 2025-01-22 00:08:49 +00:00
51cb1875bb Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12839491049
2025-01-18 01:19:32 +00:00
0b60a47cde Noteblock instrument changes from 1.21.50 (#6596)
Good thing this isn't saved on disk :|
2025-01-17 19:56:19 +00:00
d1066d0199 Bump build/php from 56cec11 to ae94694 (#6595) 2025-01-17 19:54:48 +00:00
f349ce75e4 Player: add ability to get & set flight speed multiplier (#6076)
Since this doesn't directly correspond to flight speed (it's multiplied by different values depending on whether sprinting or not, and possibly other states), "multiplier" was preferred instead of directly calling it flight speed.

Default value is 0.05.
2025-01-09 20:13:46 +00:00
b3f15435cc Projectile: clean up dodgy code 2025-01-08 02:31:50 +00:00
847ae26cad PHPStan: don't remember possibly-impure function return values
I don't think we get much benefit from this, and the assumption that functions with a return value are pure is sketchy.
In any case, it's better to avoid these repeated calls anyway.
2025-01-08 02:04:06 +00:00
d42ec06647 ZippedResourcePack: don't pass exception code to new exception
this is a BUT (int|string) under PHPStan, and we don't need the errors. We don't care about this code anyway.
2025-01-08 01:48:55 +00:00
5e0f03dff0 Stub PalettedBlockArray functions that work with arrays
and workaround PHPStan stupidity
2025-01-08 01:48:15 +00:00
4a83920db9 PlayerPreLoginEvent: improve array type info 2025-01-08 01:47:04 +00:00
0a16daa619 Avoid dodgy array_flip hash building
the conventional way is using array_keys and array_fill_keys. Behaviour is more predictable & also avoids benevolent union fuckery from PHPStan.
2025-01-08 01:45:28 +00:00
e34f34f9f4 Update BedrockProtocol dependency 2025-01-07 23:09:28 +00:00
e8c4b743b5 LevelDB: stop overriding types from NBT
NBT has better quality type info already
2025-01-07 22:54:10 +00:00
689a7996b9 Update NBT dependency 2025-01-07 22:51:38 +00:00
794641c0f8 Utils: split some horrifying code across multiple lines 2025-01-07 22:35:19 +00:00
9633b7d8a7 Update to PHPStan 2.x 2025-01-07 22:34:43 +00:00
d25ec58a6f AsyncPoolTest: phpdoc 2025-01-07 22:25:37 +00:00
d69a887b0d Utils: fix parameter doc for printableExceptionInfo() 2025-01-07 22:24:26 +00:00
38441a6ba3 build: avoid weak comparison 2025-01-07 22:23:16 +00:00
47cb04f6a6 tools: fix PHPStan 2.0 issues 2025-01-07 22:15:50 +00:00
b1c7fc017a CS 2025-01-07 22:13:20 +00:00
cd59e272bc PHPStan 2.0 fixes 2025-01-07 22:10:42 +00:00
7b1b35ab1f generator: fixup issues reported by PHPStan 2.0 2025-01-07 22:07:38 +00:00
28d31c97f8 Server: fixup PHPStan 2.x reported issues 2025-01-07 22:05:01 +00:00
a17512de93 Command: don't trust plugins not to pass junk 2025-01-06 23:26:13 +00:00
601be3fb33 stfu 2025-01-06 23:09:26 +00:00
2e32c50670 NetworkSession: apparently aliases are already a list at this point??? 2025-01-06 23:08:48 +00:00
d1fa6edc50 InGamePacketHandler: fix weak comparisons 2025-01-06 23:08:18 +00:00
a1ba8bc3da NetworkSession: improve PHPDoc types 2025-01-06 23:07:54 +00:00
73edb8799d SignalHandler: fixed dodgy setup logic 2025-01-06 23:06:19 +00:00
9592f066f3 PHPDoc: Restrict ReversePriorityQueue to numeric priorities 2025-01-06 23:05:49 +00:00
db9ba83001 Make some assumptions about proc_open() 2025-01-06 23:05:06 +00:00
1b2d2a3fe1 plugin: improve PHPDocs and type compliance 2025-01-06 23:04:00 +00:00
84ec8b7abe Removed dead error patterns
I do think these are PHPStan bugs, since the trait should inherit the parent class's doc comment
But for the sake of catching more bugs, these doc comments have been manually added anyway.
2025-01-06 23:02:18 +00:00
357dfb5c7e Fixed build 2025-01-06 23:01:14 +00:00
0358b7dce4 utils: avoid weak comparisons 2025-01-06 22:53:35 +00:00
97c5902ae2 Internet: make postURL() error reporting behaviour more predictable
err is now always set to null when doing a new operation.

previously, if the same var was used multiple times and a previous one failed,
code might think that a previous error belonged to the current operation.
2025-01-06 22:52:05 +00:00
9a130bce32 Config: remove bad assumptions about string root keys
these could just as easily be integers and the code should still work.
2025-01-06 22:50:25 +00:00
20849d6268 Fixed potential crashes in type ID tests
if the constants had any non-stringable values, these would blow up.
this would still be fine in the sense that the tests would fail, but better that they fail gracefully if possible.
2025-01-06 22:48:22 +00:00
b6bd3ef30c Improve PHPDocs in world package 2025-01-06 22:46:16 +00:00
c5a1c15389 TimingsCommand: beware crash on invalid timings server response 2025-01-06 22:44:17 +00:00
e30ae487dc SimpleCommandMap: ensure we always pass a list to Command::setAliases()
some offsets may have been removed if the alias failed to be registered.
2025-01-06 22:44:17 +00:00
59f6c85105 Command: mark execute $args as being list<string> 2025-01-06 22:44:17 +00:00
90f0b85d2e Eliminate weak comparisons in entity package
Weak comparisons were used in cases when we were worried about comparing int and float.

In some cases (particularly involving Vector3) we do need to be wary of this, so floatval() is used to avoid incorrect type comparisons.
In other cases, we were already exclusively comparing float-float, so weak compare wasn't needed anyway.
2025-01-06 22:44:17 +00:00
8ee70b209e MemoryDump: fix PHPDoc types 2025-01-06 22:44:16 +00:00
5c905d9a95 BlockBreakInfo: use strict comparison
weak compare isn't needed here since this can be float/float
2025-01-06 22:44:16 +00:00
8b23231537 Fixup PHPDoc for blocks 2025-01-06 22:44:16 +00:00
8e039f2711 Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12615442245
2025-01-05 01:37:22 +00:00
4a4572131f Bump shivammathur/setup-php in the github-actions group (#6591) 2025-01-04 22:26:14 +00:00
3da0b82b86 Merge branch 'stable' into minor-next 2025-01-03 19:26:45 +00:00
da62eb9f33 ... 2025-01-03 19:26:24 +00:00
09c434983b Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12510342531
2024-12-27 01:23:47 +00:00
fbaa125d0c Bump build/php from 9728fa5 to 56cec11 (#6588)
Bumps [build/php](https://github.com/pmmp/php-build-scripts) from `9728fa5` to `56cec11`.
- [Release notes](https://github.com/pmmp/php-build-scripts/releases)
- [Commits](9728fa57f7...56cec11745)

---
updated-dependencies:
- dependency-name: build/php
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-26 12:36:17 +00:00
6ad9dde43d Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12498201064
2024-12-26 01:23:25 +00:00
d634a5fa3d Bump build/php from b1eaaa4 to 9728fa5 (#6587)
Bumps [build/php](https://github.com/pmmp/php-build-scripts) from `b1eaaa4` to `9728fa5`.
- [Release notes](https://github.com/pmmp/php-build-scripts/releases)
- [Commits](b1eaaa48ec...9728fa57f7)

---
updated-dependencies:
- dependency-name: build/php
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-25 13:06:46 +00:00
8cea4c13c4 Merge 'stable' into 'minor-next'
Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/12487960388
2024-12-25 01:23:09 +00:00
dc2e82df7f crash.yml: add field ID for crash archive "report github issue" button 2024-12-24 16:37:18 +00:00
debf8d18fc Upgrade issue templates 2024-12-24 16:27:40 +00:00
81e3730b99 Fixed crashes containing PHP internal stack frames being flagged as plugin-caused 2024-12-24 14:20:16 +00:00
8a5eb71432 ChunkCache: track strings in cache directly instead of CompressBatchPromise
this reduces memory footprint slightly, but more importantly reduces GC workload.
Since it also reduces the work done on cache hit, it might *slightly* improve performance,
but any improvement is likely to be minimal.
2024-12-23 21:04:33 +00:00
175 changed files with 2812 additions and 982 deletions

View File

@ -1,19 +0,0 @@
---
name: API change request
about: Suggest a change, addition or removal to the plugin API
title: ''
labels: ''
assignees: ''
---
<!--- Describe the problem you want to solve -->
## Problem description
<!--- Describe what changes you want to make to solve this problem -->
## Proposed solution
<!--- (optional) describe alternative methods you've explored to achieve your goal -->
## Alternative solutions that don't require API changes

84
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@ -0,0 +1,84 @@
name: Bug report
description: Report a feature of PocketMine-MP not working as expected
body:
- type: markdown
attributes:
value: |
## Plugin information
> [!IMPORTANT]
> It's strongly recommended to test for bugs without plugins before reporting an issue.
> This helps avoid wasting maintainers' time on bugs that are not actually caused by PocketMine-MP.
>
> If you're not sure whether a plugin might be causing your issue, please seek help on our [Discord](https://discord.gg/bmSAZBG) before writing an issue.
- type: dropdown
attributes:
label: Plugin information
options:
- "I haven't tested without plugins"
- Bug happens without plugins
- Bug only happens with certain plugins (describe below)
validations:
required: true
- type: markdown
attributes:
value: |
## Bug description
> [!TIP]
> Helpful information to include:
> - Steps to reproduce the issue
> - Error backtraces
> - Crashdumps
> - Plugin code that triggers the issue
> - List of installed plugins (use /plugins)
> [!IMPORTANT]
> **Steps to reproduce are critical to finding the cause of the problem!**
> Without reproducing steps, the issue will probably not be solvable and may be closed.
- type: textarea
attributes:
label: Problem description
description: Describe the problem, and how you encountered it
placeholder: e.g. Steps to reproduce the issue
validations:
required: true
- type: textarea
attributes:
label: Expected behaviour
description: What did you expect to happen?
validations:
required: true
- type: markdown
attributes:
value: |
## Version, OS and game info
- type: input
attributes:
label: PocketMine-MP version
placeholder: Use the /version command in PocketMine-MP
validations:
required: true
- type: input
attributes:
label: PHP version
placeholder: Use the /version command in PocketMine-MP
validations:
required: true
- type: input
attributes:
label: Server OS
placeholder: Use the /version command in PocketMine-MP
validations:
required: true
- type: input
attributes:
label: Game version (if applicable)
placeholder: e.g. Android, iOS, Windows, Xbox, PS4, Switch
validations:
required: false

View File

@ -1,37 +0,0 @@
---
name: Bug report
about: Unexpected non-crash behaviour (except missing gameplay features)
title: ''
labels: ''
assignees: ''
---
### Issue description
- Expected result: What were you expecting to happen?
- Actual result: What actually happened?
### Steps to reproduce the issue
1. ...
2. ...
### OS and versions
<!-- try the `version` command | LATEST IS NOT A VALID VERSION -->
* PocketMine-MP:
* PHP:
* Using JIT: yes/no (delete as appropriate) <!-- look for the giant yellow warning in the log that says you're using JIT -->
* Server OS:
* Game version: Android/iOS/Win10/Xbox/PS4/Switch (delete as appropriate)
### Plugins
<!--- use the `plugins` command and paste the output below -->
- If you remove all plugins, does the issue still occur?
- If the issue is **not** reproducible without plugins:
- Have you asked for help on our forums before creating an issue?
- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section
### Crashdump, backtrace or other files
<!--- Submit crashdumps at https://crash.pmmp.io and paste a link -->
<!--- Use gist or anything else to add other files and add links here -->

View File

@ -1,16 +0,0 @@
---
name: Crash
about: Report a crash in PocketMine-MP (not plugins)
title: Server crashed
labels: ''
assignees: ''
---
<!--- submit crashdump files to https://crash.pmmp.io -->
<!--- or, copy the data between ===BEGIN CRASH DUMP=== and ===END CRASH DUMP and paste it on a site like https://pastebin.com -->
<!--- DON'T JUST PASTE the crashdump into an issue -->
Link to crashdump:
<!--- write additional information about the crash to help us find the problem -->
### Additional comments (optional)

25
.github/ISSUE_TEMPLATE/crash.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Crash
description: Report a crash in PocketMine-MP (not plugins)
title: Server crashed
body:
- type: markdown
attributes:
value: |
> [!TIP]
> Submit crashdump `.log` files to the [Crash Archive](https://crash.pmmp.io/submit).
> If you can't submit the crashdump to the Crash Archive, paste it on a site like [GitHub Gist](https://gist.github.com) or [Pastebin](https://pastebin.com).
> [!CAUTION]
> DON'T paste the crashdump data directly into an issue.
- type: input
id: crashdump-url
attributes:
label: Link to crashdump
validations:
required: true
- type: textarea
attributes:
label: Additional comments (optional)
description: Any other information that might help us solve the problem

View File

@ -0,0 +1,19 @@
name: Feature addition, change, or removal
description: Propose adding new features, or changing/removing existing ones
body:
- type: textarea
attributes:
label: Problem description
description: Explain why a change is needed
validations:
required: true
- type: textarea
attributes:
label: Proposed solution
description: Describe what changes you think should be made
validations:
required: true
- type: textarea
attributes:
label: "Alternative solutions or workarounds"
description: "Describe other ways you've explored to achieve your goal"

View File

@ -53,7 +53,7 @@ jobs:
run: echo NAME=$(echo "${GITHUB_REPOSITORY,,}") >> $GITHUB_OUTPUT
- name: Build image for tag
uses: docker/build-push-action@v6.10.0
uses: docker/build-push-action@v6.15.0
with:
push: true
context: ./pocketmine-mp
@ -66,7 +66,7 @@ jobs:
- name: Build image for major tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v6.10.0
uses: docker/build-push-action@v6.15.0
with:
push: true
context: ./pocketmine-mp
@ -79,7 +79,7 @@ jobs:
- name: Build image for minor tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v6.10.0
uses: docker/build-push-action@v6.15.0
with:
push: true
context: ./pocketmine-mp
@ -92,7 +92,7 @@ jobs:
- name: Build image for latest tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v6.10.0
uses: docker/build-push-action@v6.15.0
with:
push: true
context: ./pocketmine-mp

View File

@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.31.1
uses: shivammathur/setup-php@2.32.0
with:
php-version: 8.2

View File

@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@2.31.1
uses: shivammathur/setup-php@2.32.0
with:
php-version: 8.2

View File

@ -87,7 +87,7 @@ jobs:
submodules: true
- name: Setup PHP
uses: shivammathur/setup-php@2.31.1
uses: shivammathur/setup-php@2.32.0
with:
php-version: ${{ env.PHP_VERSION }}
@ -165,7 +165,7 @@ jobs:
${{ github.workspace }}/core-permissions.rst
- name: Create draft release
uses: ncipollo/release-action@v1.14.0
uses: ncipollo/release-action@v1.16.0
id: create-draft
with:
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json,${{ github.workspace }}/core-permissions.rst
@ -182,6 +182,8 @@ jobs:
:information_source: Download the recommended PHP binary [here](${{ steps.php-binary-url.outputs.PHP_BINARY_URL }}).
:warning: Found a bug? Report it on our [issue tracker](${{ github.server_url }}/${{ github.repository }}/issues). **We can't fix bugs if you don't report them.**
- name: Post draft release URL on PR
if: github.event_name == 'pull_request_target'
uses: thollander/actions-comment-pull-request@v3

View File

@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.31.1
uses: shivammathur/setup-php@2.32.0
with:
php-version: 8.2
tools: php-cs-fixer:3.49

View File

@ -65,6 +65,8 @@ PocketMine-MP accepts community contributions! The following resources will be u
* [Building and running PocketMine-MP from source](BUILDING.md)
* [Contributing Guidelines](CONTRIBUTING.md)
New here? Check out [issues with the "Easy task" label](https://github.com/pmmp/PocketMine-MP/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Easy%20task%22) for things you could work to familiarise yourself with the codebase.
## Donate
PocketMine-MP is free, but it requires a lot of time and effort from unpaid volunteers to develop. Donations enable us to keep delivering support for new versions and adding features your players love.

View File

@ -36,7 +36,7 @@ require dirname(__DIR__) . '/vendor/autoload.php';
*/
$options = [
"base_version" => VersionInfo::BASE_VERSION,
"major_version" => fn() => explode(".", VersionInfo::BASE_VERSION)[0],
"major_version" => fn() => explode(".", VersionInfo::BASE_VERSION, limit: 2)[0],
"mcpe_version" => ProtocolInfo::MINECRAFT_VERSION_NETWORK,
"is_dev" => VersionInfo::IS_DEVELOPMENT_BUILD,
"changelog_file_name" => function() : string{

View File

@ -28,6 +28,7 @@ use function dirname;
use function fclose;
use function fopen;
use function fwrite;
use function is_dir;
use function is_file;
use function scandir;
use function str_replace;
@ -59,7 +60,7 @@ foreach($files as $file){
continue;
}
$path = Path::join(BEDROCK_DATA_PATH, $file);
if(!is_file($path)){
if(!is_file($path) && !is_dir($path)){
continue;
}
@ -67,6 +68,7 @@ foreach($files as $file){
'README.md',
'LICENSE',
'composer.json',
'.github'
] as $ignored){
if($file === $ignored){
continue 2;

View File

@ -129,7 +129,7 @@ function buildPhar(string $pharPath, string $basePath, array $includedPaths, arr
}
function main() : void{
if(ini_get("phar.readonly") == 1){
if(ini_get("phar.readonly") === "1"){
echo "Set phar.readonly to 0 with -dphar.readonly=0" . PHP_EOL;
exit(1);
}

View File

@ -127,3 +127,13 @@ Released 9th December 2024.
## Internals
- Removed legacy `build/make-release.php` script. This script is no longer used, as all releases should now follow the PR workflow.
# 5.23.3
Released 22nd January 2025.
## Fixes
- Fixed crashes with PHP internal stack frames being flagged as plugin crashes.
- Fixed note block instrument sounds in 1.21.50.
## Internals
- Updated GitHub issue templates to use issue forms.

108
changelogs/5.24.md Normal file
View File

@ -0,0 +1,108 @@
# 5.24.0
Released 22nd January 2025.
This is a minor feature release, including new gameplay features, performance improvements, and minor API additions.
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
Do not update plugin minimum API versions unless you need new features added in this release.
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
## Performance
- PHP garbage collection is now managed by the server, instead of being automatically triggered by PHP.
- The mechanism for GC triggering is designed to mimic PHP's to avoid behavioural changes. Only the place it's triggered from should be significantly different.
- This change also avoids unnecessary GCs during object-heavy operations, such as encoding `CraftingDataPacket`. As such, performance during server join should see an improvement.
- Timings is now able to directly measure the impact of GC. Previously, GC would show up as random spikes under random timers, skewing timing results.
- `ChunkCache` now uses `string` for completed caches directly instead of keeping them wrapped in `CompressBatchPromise`s. This reduces memory usage, improves performance, and reduces GC workload.
## Configuration
- The following settings have been removed from `pocketmine.yml` and will no longer have any effect:
- `memory.garbage-collection.collect-async-worker` (now always `true`)
- `memory.garbage-collection.low-memory-trigger` (now always `true`)
- `memory.max-chunks.trigger-chunk-collect` (now always `true`)
- `memory.world-caches.disable-chunk-cache` (now always `true`)
- `memory.world-caches.low-memory-trigger` (now always `true`)
## Gameplay
- Added the following new blocks:
- All types of pale oak wood, and leaves
- Resin
- Resin Bricks, Slabs, Stairs, and Walls
- Resin Clump
- Chiseled Resin Bricks
- Some blocks have had their tool tier requirements adjusted to match latest Bedrock updates.
- Added the following new items:
- Resin Brick
- Music Disc - Creator
- Music Disc - Creator (Music Box)
- Music Disc - Precipice
- Music Disc - Relic
## API
### General
- Many places had their PHPDoc improved to address issues highlighted by PHPStan 2.x. This may cause new, previously unreported issues to be reported in plugins using PHPStan.
### `pocketmine`
- The following methods have been deprecated:
- `MemoryManager->canUseChunkCache()`
- `MemoryManager::dumpMemory()` - relocated to `MemoryDump` class
### `pocketmine\item`
- The following new enum cases have been added:
- `RecordType::DISK_CREATOR`
- `RecordType::DISK_CREATOR_MUSIC_BOX`
- `RecordType::DISK_PRECIPICE`
- `RecordType::DISK_RELIC`
### `pocketmine\player`
- The following new methods have been added:
- `public Player->getFlightSpeedMultiplier() : float` - a base multiplier for player's flight speed
- `public Player->setFlightSpeedMultiplier(float $flightSpeedMultiplier) : void` - sets the player's flight speed multiplier
- The following new constants have been added:
- `Player::DEFAULT_FLIGHT_SPEED_MULTIPLIER`
### `pocketmine\utils`
- The following new methods have been added:
- `public static TextFormat::javaToBedrock(string $string) : string` - removes unsupported Java Edition format codes to prevent them being incorrectly displayed on Bedrock
- The following methods have behavioural changes:
- `TextFormat::toHTML()` now converts `§m` to redstone red (instead of strikethrough), and `§n` to copper orange (instead of underline). This is because the codes previously used for `STRIKETHROUGH` and `UNDERLINE` conflict with the new material codes introduced by Minecraft Bedrock.
- `Terminal::toANSI()` now converts `§m` to redstone red (instead of strikethrough), and `§n` to copper orange (instead of underline), as above. However, underline and strikethrough can still be used on the terminal using `Terminal::$FORMAT_UNDERLINE` and `Terminal::$FORMAT_STRIKETHROUGH` respectively.
- The following new constants have been added:
- `TextFormat::MATERIAL_QUARTZ`
- `TextFormat::MATERIAL_IRON`
- `TextFormat::MATERIAL_NETHERITE`
- `TextFormat::MATERIAL_REDSTONE`
- `TextFormat::MATERIAL_COPPER`
- `TextFormat::MATERIAL_GOLD`
- `TextFormat::MATERIAL_EMERALD`
- `TextFormat::MATERIAL_DIAMOND`
- `TextFormat::MATERIAL_LAPIS`
- `TextFormat::MATERIAL_AMETHYST`
- The following constants have been deprecated:
- `TextFormat::STRIKETHROUGH`
- `TextFormat::UNDERLINE`
- The following static properties have been added:
- `Terminal::$COLOR_MATERIAL_QUARTZ`
- `Terminal::$COLOR_MATERIAL_IRON`
- `Terminal::$COLOR_MATERIAL_NETHERITE`
- `Terminal::$COLOR_MATERIAL_REDSTONE`
- `Terminal::$COLOR_MATERIAL_COPPER`
- `Terminal::$COLOR_MATERIAL_GOLD`
- `Terminal::$COLOR_MATERIAL_EMERALD`
- `Terminal::$COLOR_MATERIAL_DIAMOND`
- `Terminal::$COLOR_MATERIAL_LAPIS`
- `Terminal::$COLOR_MATERIAL_AMETHYST`
## Tools
- Fixed some UI issues in `tools/convert-world.php`
## Internals
- Block cache in `World` is now size-limited. This prevents memory exhaustion when plugins call `getBlock()` many thousands of times with cache misses.
- `RakLibServer` now disables PHP GC. As RakLib doesn't generate any unmanaged cycles, GC is just a waste of CPU time in this context.
- `MemoryManager` now has the responsibility for triggering cycle GC. It's checked every tick, but GC won't take place unless the GC threshold is exceeded, similar to PHP.
- This mechanism could probably do with alterations to better suit PocketMine-MP, but it was chosen to mimic PHP's own GC to minimize behavioural changes for now.
- `AsyncTask` now triggers cycle GC after `onRun()` completes. As with `MemoryManager`, this is based on a threshold designed to mimic PHP's own behaviour.
- `FormatConverter` now performs world provider GC periodically. This is not needed with current active providers, but was found to be a problem while developing custom providers.
- Various internal adjustments were made to avoid returning incorrectly-keyed arrays in the code. These changes shouldn't affect anything as the arrays should have been properly ordered anyway.
- Many places that previously used `==` and `!=` have been updated to use strict variants. This kind of change needs to be done carefully to avoid breaking `int|float` comparisons.

52
changelogs/5.25.md Normal file
View File

@ -0,0 +1,52 @@
# 5.25.0
Released 16th February 2025.
This is a support release for Minecraft: Bedrock Edition 1.21.60. It also includes some minor API additions supporting new features in this version.
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
Do not update plugin minimum API versions unless you need new features added in this release.
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
## General
- Added support for Minecraft: Bedrock Edition 1.21.60.
- Removed support for earlier versions.
## Documentation
- Fixed the documentation of `Utils::getOS()`. It now refers to the `Utils::OS_*` constants instead of a list of hardcoded strings.
## API
### `pocketmine\inventory`
This release allows plugins to decide which creative tab they want to add their new items to.
It also allows creating new collapsible groups of items, and modifying or removing existing ones.
- The following new methods have been added:
- `public CreativeInventory->getAllEntries() : list<CreativeInventoryEntry>` - returns an array of objects, each containing a creative item and information about its category and collapsible group (if applicable).
- `public CreativeInventory->getEntry(int $index) : ?CreativeInventoryEntry` - returns the creative item with the specified identifier, or `null` if not found
- The following methods have signature changes:
- `CreativeInventory->add()` now accepts two additional optional parameters: `CreativeCategory $category, ?CreativeGroup $group`. If not specified, the item will be added to the Items tab without a group.
- The following new classes have been added:
- `CreativeCategory` - enum of possible creative inventory categories (each has its own tab on the GUI)
- `CreativeGroup` - contains information about a collapsible group of creative items, including tooltip text and icon
- `CreativeInventoryEntry` - contains information about a creative inventory item, including its category and collapsible group (if applicable)
## Internals
- `CreativeContentPacket` is no longer fully cached due to the requirement for translation context during construction. The individual items are still cached (which is the most expensive part), but the packet itself is now constructed on demand, and group entries are constructed on the fly. This may affect performance, but this has not been investigated.
- `BedrockDataFiles` now includes constants for folders at the top level of `BedrockData` as well as files.
- The structure of creative data in `BedrockData` was changed to accommodate item category and grouping information. `creativeitems.json` has been replaced by `creative/*.json`, which contain information about item grouping and also segregates item lists per category.
- New information was added to `required_item_list.json` in `BedrockData`, as the server is now required to send item component NBT data in some cases.
# 5.25.1
Released 26th February 2025.
## Fixes
- Fixed confusing exception message when a block-breaking tool has an efficiency value of zero.
- Fixed incorrect facing of doors since 1.21.60 (resulted in mismatched AABBs between client & server, rendering glitches etc.)
- Resource pack UUIDs are now validated on load. Previously, invalid UUIDs would be accepted, and potentially cause a server crash on player join.
# 5.25.2
Released 4th March 2025.
## Fixes
- Added limits to various `explode()` calls.

View File

@ -33,15 +33,15 @@
"composer-runtime-api": "^2.0",
"adhocore/json-comment": "~1.2.0",
"netresearch/jsonmapper": "~v5.0.0",
"pocketmine/bedrock-block-upgrade-schema": "~5.0.0+bedrock-1.21.40",
"pocketmine/bedrock-data": "~2.15.0+bedrock-1.21.50",
"pocketmine/bedrock-block-upgrade-schema": "~5.1.0+bedrock-1.21.60",
"pocketmine/bedrock-data": "~4.0.0+bedrock-1.21.60",
"pocketmine/bedrock-item-upgrade-schema": "~1.14.0+bedrock-1.21.50",
"pocketmine/bedrock-protocol": "~35.0.0+bedrock-1.21.50",
"pocketmine/binaryutils": "^0.2.1",
"pocketmine/bedrock-protocol": "~36.0.0+bedrock-1.21.60",
"pocketmine/binaryutils": "dev-experimental/read-ops-accounting as 0.2.6",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/color": "^0.3.0",
"pocketmine/errorhandler": "^0.7.0",
"pocketmine/locale-data": "~2.22.0",
"pocketmine/locale-data": "~2.24.0",
"pocketmine/log": "^0.4.0",
"pocketmine/math": "~1.0.0",
"pocketmine/nbt": "~1.0.0",
@ -52,9 +52,9 @@
"symfony/filesystem": "~6.4.0"
},
"require-dev": {
"phpstan/phpstan": "1.11.11",
"phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0",
"phpstan/phpstan": "2.1.6",
"phpstan/phpstan-phpunit": "^2.0.0",
"phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^10.5.24"
},
"autoload": {

221
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "732102eca72dc1d29e7b67dfbce07653",
"content-hash": "415cb668882a32039066467bb308421f",
"packages": [
{
"name": "adhocore/json-comment",
@ -67,16 +67,16 @@
},
{
"name": "brick/math",
"version": "0.12.1",
"version": "0.12.2",
"source": {
"type": "git",
"url": "https://github.com/brick/math.git",
"reference": "f510c0a40911935b77b86859eb5223d58d660df1"
"reference": "901eddb1e45a8e0f689302e40af871c181ecbe40"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1",
"reference": "f510c0a40911935b77b86859eb5223d58d660df1",
"url": "https://api.github.com/repos/brick/math/zipball/901eddb1e45a8e0f689302e40af871c181ecbe40",
"reference": "901eddb1e45a8e0f689302e40af871c181ecbe40",
"shasum": ""
},
"require": {
@ -85,7 +85,7 @@
"require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^10.1",
"vimeo/psalm": "5.16.0"
"vimeo/psalm": "6.8.8"
},
"type": "library",
"autoload": {
@ -115,7 +115,7 @@
],
"support": {
"issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.12.1"
"source": "https://github.com/brick/math/tree/0.12.2"
},
"funding": [
{
@ -123,7 +123,7 @@
"type": "github"
}
],
"time": "2023-11-29T23:19:16+00:00"
"time": "2025-02-26T10:21:45+00:00"
},
{
"name": "netresearch/jsonmapper",
@ -178,16 +178,16 @@
},
{
"name": "pocketmine/bedrock-block-upgrade-schema",
"version": "5.0.0",
"version": "5.1.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git",
"reference": "20dd5c11e9915bacea4fe2cf649e1d23697a6e52"
"reference": "2218512e4b91f5bfd09ef55f7a4c4b04e169e41a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/20dd5c11e9915bacea4fe2cf649e1d23697a6e52",
"reference": "20dd5c11e9915bacea4fe2cf649e1d23697a6e52",
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/2218512e4b91f5bfd09ef55f7a4c4b04e169e41a",
"reference": "2218512e4b91f5bfd09ef55f7a4c4b04e169e41a",
"shasum": ""
},
"type": "library",
@ -198,22 +198,22 @@
"description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves",
"support": {
"issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues",
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/5.0.0"
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/5.1.0"
},
"time": "2024-11-03T14:13:50+00:00"
"time": "2025-02-11T17:41:44+00:00"
},
{
"name": "pocketmine/bedrock-data",
"version": "2.15.0+bedrock-1.21.50",
"version": "4.0.0+bedrock-1.21.60",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockData.git",
"reference": "6e819f36d781866ce63d2406be2ce7f2d1afd9ad"
"reference": "2e5f16ec2facac653f3f894f22eb831d880ba98e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/6e819f36d781866ce63d2406be2ce7f2d1afd9ad",
"reference": "6e819f36d781866ce63d2406be2ce7f2d1afd9ad",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/2e5f16ec2facac653f3f894f22eb831d880ba98e",
"reference": "2e5f16ec2facac653f3f894f22eb831d880ba98e",
"shasum": ""
},
"type": "library",
@ -224,9 +224,9 @@
"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.21.50"
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.21.60"
},
"time": "2024-12-04T12:59:12+00:00"
"time": "2025-02-16T15:56:56+00:00"
},
{
"name": "pocketmine/bedrock-item-upgrade-schema",
@ -256,16 +256,16 @@
},
{
"name": "pocketmine/bedrock-protocol",
"version": "35.0.0+bedrock-1.21.50",
"version": "36.0.0+bedrock-1.21.60",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "bd1ec79bae8c88aa984e1c5f0c3313be5ae9b435"
"reference": "2057de319c5c551001c2a544e08d1bc7727d9963"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/bd1ec79bae8c88aa984e1c5f0c3313be5ae9b435",
"reference": "bd1ec79bae8c88aa984e1c5f0c3313be5ae9b435",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/2057de319c5c551001c2a544e08d1bc7727d9963",
"reference": "2057de319c5c551001c2a544e08d1bc7727d9963",
"shasum": ""
},
"require": {
@ -278,10 +278,10 @@
"ramsey/uuid": "^4.1"
},
"require-dev": {
"phpstan/phpstan": "1.11.9",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpstan/phpstan-strict-rules": "^1.0.0",
"phpunit/phpunit": "^9.5 || ^10.0"
"phpstan/phpstan": "2.1.0",
"phpstan/phpstan-phpunit": "^2.0.0",
"phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^9.5 || ^10.0 || ^11.0"
},
"type": "library",
"autoload": {
@ -296,22 +296,22 @@
"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/35.0.0+bedrock-1.21.50"
"source": "https://github.com/pmmp/BedrockProtocol/tree/36.0.0+bedrock-1.21.60"
},
"time": "2024-12-04T13:02:00+00:00"
"time": "2025-02-16T15:59:08+00:00"
},
{
"name": "pocketmine/binaryutils",
"version": "0.2.6",
"version": "dev-experimental/read-ops-accounting",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BinaryUtils.git",
"reference": "ccfc1899b859d45814ea3592e20ebec4cb731c84"
"reference": "8cfa34c9d5aae11886a4142c172cff05f1e87ee2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/ccfc1899b859d45814ea3592e20ebec4cb731c84",
"reference": "ccfc1899b859d45814ea3592e20ebec4cb731c84",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8cfa34c9d5aae11886a4142c172cff05f1e87ee2",
"reference": "8cfa34c9d5aae11886a4142c172cff05f1e87ee2",
"shasum": ""
},
"require": {
@ -320,9 +320,9 @@
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "~1.10.3",
"phpstan/phpstan-phpunit": "^1.0",
"phpstan/phpstan-strict-rules": "^1.0.0",
"phpstan/phpstan": "2.1.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0.0",
"phpunit/phpunit": "^9.5 || ^10.0 || ^11.0"
},
"type": "library",
@ -338,9 +338,9 @@
"description": "Classes and methods for conveniently handling binary data",
"support": {
"issues": "https://github.com/pmmp/BinaryUtils/issues",
"source": "https://github.com/pmmp/BinaryUtils/tree/0.2.6"
"source": "https://github.com/pmmp/BinaryUtils/tree/experimental/read-ops-accounting"
},
"time": "2024-03-04T15:04:17+00:00"
"time": "2025-03-11T11:50:46+00:00"
},
{
"name": "pocketmine/callback-validator",
@ -471,16 +471,16 @@
},
{
"name": "pocketmine/locale-data",
"version": "2.22.1",
"version": "2.24.0",
"source": {
"type": "git",
"url": "https://github.com/pmmp/Language.git",
"reference": "fa4e377c437391cfcfdedd08eea3a848eabd1b49"
"reference": "6ec5e92c77a2102b2692763733e4763012facae9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/Language/zipball/fa4e377c437391cfcfdedd08eea3a848eabd1b49",
"reference": "fa4e377c437391cfcfdedd08eea3a848eabd1b49",
"url": "https://api.github.com/repos/pmmp/Language/zipball/6ec5e92c77a2102b2692763733e4763012facae9",
"reference": "6ec5e92c77a2102b2692763733e4763012facae9",
"shasum": ""
},
"type": "library",
@ -488,9 +488,9 @@
"description": "Language resources used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/Language/issues",
"source": "https://github.com/pmmp/Language/tree/2.22.1"
"source": "https://github.com/pmmp/Language/tree/2.24.0"
},
"time": "2024-12-06T14:44:17+00:00"
"time": "2025-02-16T20:46:34+00:00"
},
{
"name": "pocketmine/log",
@ -576,16 +576,16 @@
},
{
"name": "pocketmine/nbt",
"version": "1.0.0",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "20540271cb59e04672cb163dca73366f207974f1"
"reference": "53db37487bc5ddbfbd84247966e1a073bdcfdb7d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/20540271cb59e04672cb163dca73366f207974f1",
"reference": "20540271cb59e04672cb163dca73366f207974f1",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/53db37487bc5ddbfbd84247966e1a073bdcfdb7d",
"reference": "53db37487bc5ddbfbd84247966e1a073bdcfdb7d",
"shasum": ""
},
"require": {
@ -595,8 +595,8 @@
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "1.10.25",
"phpstan/phpstan-strict-rules": "^1.0",
"phpstan/phpstan": "2.1.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.5"
},
"type": "library",
@ -612,9 +612,9 @@
"description": "PHP library for working with Named Binary Tags",
"support": {
"issues": "https://github.com/pmmp/NBT/issues",
"source": "https://github.com/pmmp/NBT/tree/1.0.0"
"source": "https://github.com/pmmp/NBT/tree/1.0.1"
},
"time": "2023-07-14T13:01:49+00:00"
"time": "2025-01-07T22:47:46+00:00"
},
{
"name": "pocketmine/raklib",
@ -1013,8 +1013,8 @@
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
@ -1092,8 +1092,8 @@
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
@ -1150,16 +1150,16 @@
"packages-dev": [
{
"name": "myclabs/deep-copy",
"version": "1.12.1",
"version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
"reference": "024473a478be9df5fdaca2c793f2232fe788e414"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
"reference": "024473a478be9df5fdaca2c793f2232fe788e414",
"shasum": ""
},
"require": {
@ -1198,7 +1198,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
},
"funding": [
{
@ -1206,20 +1206,20 @@
"type": "tidelift"
}
],
"time": "2024-11-08T17:47:46+00:00"
"time": "2025-02-12T12:17:51+00:00"
},
{
"name": "nikic/php-parser",
"version": "v5.3.1",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
"reference": "447a020a1f875a434d62f2a401f53b82a396e494"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
"reference": "447a020a1f875a434d62f2a401f53b82a396e494",
"shasum": ""
},
"require": {
@ -1262,9 +1262,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
},
"time": "2024-10-08T18:51:32+00:00"
"time": "2024-12-30T11:07:19+00:00"
},
{
"name": "phar-io/manifest",
@ -1386,20 +1386,20 @@
},
{
"name": "phpstan/phpstan",
"version": "1.11.11",
"version": "2.1.6",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3"
"reference": "6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3",
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c",
"reference": "6eaec7c6c9e90dcfe46ad1e1ffa5171e2dab641c",
"shasum": ""
},
"require": {
"php": "^7.2|^8.0"
"php": "^7.4|^8.0"
},
"conflict": {
"phpstan/phpstan-shim": "*"
@ -1440,34 +1440,33 @@
"type": "github"
}
],
"time": "2024-08-19T14:37:29+00:00"
"time": "2025-02-19T15:46:42+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
"version": "1.4.0",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git",
"reference": "f3ea021866f4263f07ca3636bf22c64be9610c11"
"reference": "d09e152f403c843998d7a52b5d87040c937525dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/f3ea021866f4263f07ca3636bf22c64be9610c11",
"reference": "f3ea021866f4263f07ca3636bf22c64be9610c11",
"url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/d09e152f403c843998d7a52b5d87040c937525dd",
"reference": "d09e152f403c843998d7a52b5d87040c937525dd",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpstan/phpstan": "^1.11"
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0.4"
},
"conflict": {
"phpunit/phpunit": "<7.0"
},
"require-dev": {
"nikic/php-parser": "^4.13.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-strict-rules": "^1.5.1",
"phpunit/phpunit": "^9.5"
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6"
},
"type": "phpstan-extension",
"extra": {
@ -1490,34 +1489,33 @@
"description": "PHPUnit extensions and rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
"source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.0"
"source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.4"
},
"time": "2024-04-20T06:39:00+00:00"
"time": "2025-01-22T13:07:38+00:00"
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "1.6.0",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "363f921dd8441777d4fc137deb99beb486c77df1"
"reference": "8b88b5f818bfa301e0c99154ab622dace071c3ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/363f921dd8441777d4fc137deb99beb486c77df1",
"reference": "363f921dd8441777d4fc137deb99beb486c77df1",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/8b88b5f818bfa301e0c99154ab622dace071c3ba",
"reference": "8b88b5f818bfa301e0c99154ab622dace071c3ba",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpstan/phpstan": "^1.11"
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^2.0.4"
},
"require-dev": {
"nikic/php-parser": "^4.13.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^9.5"
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^9.6"
},
"type": "phpstan-extension",
"extra": {
@ -1539,9 +1537,9 @@
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.0"
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.3"
},
"time": "2024-04-20T06:37:51+00:00"
"time": "2025-01-21T10:52:14+00:00"
},
{
"name": "phpunit/php-code-coverage",
@ -1866,16 +1864,16 @@
},
{
"name": "phpunit/phpunit",
"version": "10.5.38",
"version": "10.5.45",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132"
"reference": "bd68a781d8e30348bc297449f5234b3458267ae8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132",
"reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8",
"reference": "bd68a781d8e30348bc297449f5234b3458267ae8",
"shasum": ""
},
"require": {
@ -1885,7 +1883,7 @@
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.12.0",
"myclabs/deep-copy": "^1.12.1",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.1",
@ -1947,7 +1945,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38"
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45"
},
"funding": [
{
@ -1963,7 +1961,7 @@
"type": "tidelift"
}
],
"time": "2024-10-28T13:06:21+00:00"
"time": "2025-02-06T16:08:12+00:00"
},
{
"name": "sebastian/cli-parser",
@ -2932,9 +2930,18 @@
"time": "2024-03-03T12:36:25+00:00"
}
],
"aliases": [],
"aliases": [
{
"package": "pocketmine/binaryutils",
"version": "dev-experimental/read-ops-accounting",
"alias": "0.2.6",
"alias_normalized": "0.2.6.0"
}
],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"pocketmine/binaryutils": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

View File

@ -13,12 +13,14 @@ rules:
- pocketmine\phpstan\rules\DeprecatedLegacyEnumAccessRule
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
- pocketmine\phpstan\rules\DisallowForeachByReferenceRule
- pocketmine\phpstan\rules\ExplodeLimitRule
- pocketmine\phpstan\rules\UnsafeForeachArrayOfStringRule
# - pocketmine\phpstan\rules\ThreadedSupportedTypesRule
parameters:
level: 9
checkMissingCallableSignature: true
rememberPossiblyImpureFunctionValues: false #risky to remember these, better for performance to avoid repeated calls anyway
treatPhpDocTypesAsCertain: false
bootstrapFiles:
- tests/phpstan/bootstrap.php
@ -31,6 +33,7 @@ parameters:
paths:
- build
- src
- tests/phpstan/DummyPluginOwned.php
- tests/phpstan/rules
- tests/phpunit
- tests/plugins/TesterPlugin
@ -44,6 +47,7 @@ parameters:
- pocketmine\DEBUG
- pocketmine\IS_DEVELOPMENT_BUILD
stubFiles:
- tests/phpstan/stubs/chunkutils2.stub
- tests/phpstan/stubs/JsonMapper.stub
- tests/phpstan/stubs/leveldb.stub
- tests/phpstan/stubs/pmmpthread.stub

View File

@ -83,6 +83,29 @@ network:
#DO NOT DISABLE THIS unless you understand the risks involved.
enable-encryption: true
#EXPERIMENTAL! Limit packet read operations per network session.
#This is intended to stop exploitation of packets with arrays in them.
#Note that enabling this system may cause players to be unexpectedly kicked, or it may fail to stop attackers.
#As of March 2025, the system is still in development and subject to change.
packet-read-ops-limit:
#What to do when a session's read ops budget is depleted.
#Supported actions are "none", "warn" and "kick".
deplete-action: warn
#How many backlog ticks to budget for. 200 allows for a 10-second network lag spike, or a small number of complex
#packets.
session-budget-ticks: 200
#How much to top up each session's read operations budget per tick. Recommended to set this to about 2x the
#average number of read operations per tick per session.
#Exceeding this value won't cause any action to be taken. However, consistently exceeding it will cause the
#session's budget to be depleted, resulting in action being taken.
session-budget-per-tick: 100
#Whether to collect stats for debugging. This might impact performance.
#See NetworkSession::dumpDecodeCostStats() if you want to visualize the stats yourself.
collect-stats: false
debug:
#If > 1, it will show debug messages in the console
level: 1

View File

@ -253,12 +253,12 @@ final class MemoryDump{
}
/**
* @param object[] $objects reference parameter
* @param int[] $refCounts reference parameter
* @param object[]|true[] $objects reference parameter
* @param int[] $refCounts reference parameter
*
* @phpstan-param array<string, object> $objects
* @phpstan-param array<string, object|true> $objects
* @phpstan-param array<string, int> $refCounts
* @phpstan-param-out array<string, object> $objects
* @phpstan-param-out array<string, object|true> $objects
* @phpstan-param-out array<string, int> $refCounts
*/
private static function continueDump(mixed $from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : mixed{

View File

@ -264,7 +264,7 @@ JIT_WARNING
$composerGitHash = InstalledVersions::getReference('pocketmine/pocketmine-mp');
if($composerGitHash !== null){
//we can't verify dependency versions if we were installed without using git
$currentGitHash = explode("-", VersionInfo::GIT_HASH())[0];
$currentGitHash = explode("-", VersionInfo::GIT_HASH(), 2)[0];
if($currentGitHash !== $composerGitHash){
critical_error("Composer dependencies and/or autoloader are out of sync.");
critical_error("- Current revision is $currentGitHash");

View File

@ -36,6 +36,7 @@ use pocketmine\crafting\CraftingManager;
use pocketmine\crafting\CraftingManagerFromDataHelper;
use pocketmine\crash\CrashDump;
use pocketmine\crash\CrashDumpRenderer;
use pocketmine\data\bedrock\BedrockDataFiles;
use pocketmine\entity\EntityDataHelper;
use pocketmine\entity\Location;
use pocketmine\event\HandlerListManager;
@ -138,6 +139,7 @@ use function file_put_contents;
use function filemtime;
use function fopen;
use function get_class;
use function gettype;
use function ini_set;
use function is_array;
use function is_dir;
@ -697,7 +699,7 @@ class Server{
public function removeOp(string $name) : void{
$lowercaseName = strtolower($name);
foreach($this->operators->getAll() as $operatorName => $_){
foreach(Utils::promoteKeys($this->operators->getAll()) as $operatorName => $_){
$operatorName = (string) $operatorName;
if($lowercaseName === strtolower($operatorName)){
$this->operators->remove($operatorName);
@ -918,6 +920,7 @@ class Server{
TimingsHandler::getCollectCallbacks()->add(function() : array{
$promises = [];
foreach($this->asyncPool->getRunningWorkers() as $workerId){
/** @phpstan-var PromiseResolver<list<string>> $resolver */
$resolver = new PromiseResolver();
$this->asyncPool->submitTaskToWorker(new TimingsCollectionTask($resolver), $workerId);
@ -1003,7 +1006,7 @@ class Server{
$this->commandMap = new SimpleCommandMap($this);
$this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\BEDROCK_DATA_PATH, "recipes"));
$this->craftingManager = CraftingManagerFromDataHelper::make(BedrockDataFiles::RECIPES);
$this->resourceManager = new ResourcePackManager(Path::join($this->dataPath, "resource_packs"), $this->logger);
@ -1013,7 +1016,11 @@ class Server{
copy(Path::join(\pocketmine\RESOURCE_PATH, 'plugin_list.yml'), $graylistFile);
}
try{
$pluginGraylist = PluginGraylist::fromArray(yaml_parse(Filesystem::fileGetContents($graylistFile)));
$array = yaml_parse(Filesystem::fileGetContents($graylistFile));
if(!is_array($array)){
throw new \InvalidArgumentException("Expected array for root, but have " . gettype($array));
}
$pluginGraylist = PluginGraylist::fromArray($array);
}catch(\InvalidArgumentException $e){
$this->logger->emergency("Failed to load $graylistFile: " . $e->getMessage());
$this->forceShutdownExit();
@ -1174,7 +1181,7 @@ class Server{
if($this->worldManager->getDefaultWorld() === null){
$default = $this->configGroup->getConfigString(ServerProperties::DEFAULT_WORLD_NAME, "world");
if(trim($default) == ""){
if(trim($default) === ""){
$this->logger->warning("level-name cannot be null, using default");
$default = "world";
$this->configGroup->setConfigString(ServerProperties::DEFAULT_WORLD_NAME, "world");

View File

@ -31,7 +31,7 @@ use function str_repeat;
final class VersionInfo{
public const NAME = "PocketMine-MP";
public const BASE_VERSION = "5.23.3";
public const BASE_VERSION = "5.25.3";
public const IS_DEVELOPMENT_BUILD = true;
public const BUILD_CHANNEL = "stable";

View File

@ -90,6 +90,11 @@ final class YmlServerProperties{
public const NETWORK_COMPRESSION_LEVEL = 'network.compression-level';
public const NETWORK_ENABLE_ENCRYPTION = 'network.enable-encryption';
public const NETWORK_MAX_MTU_SIZE = 'network.max-mtu-size';
public const NETWORK_PACKET_READ_OPS_LIMIT = 'network.packet-read-ops-limit';
public const NETWORK_PACKET_READ_OPS_LIMIT_COLLECT_STATS = 'network.packet-read-ops-limit.collect-stats';
public const NETWORK_PACKET_READ_OPS_LIMIT_DEPLETE_ACTION = 'network.packet-read-ops-limit.deplete-action';
public const NETWORK_PACKET_READ_OPS_LIMIT_SESSION_BUDGET_PER_TICK = 'network.packet-read-ops-limit.session-budget-per-tick';
public const NETWORK_PACKET_READ_OPS_LIMIT_SESSION_BUDGET_TICKS = 'network.packet-read-ops-limit.session-budget-ticks';
public const NETWORK_UPNP_FORWARDING = 'network.upnp-forwarding';
public const PLAYER = 'player';
public const PLAYER_SAVE_PLAYER_DATA = 'player.save-player-data';

View File

@ -70,9 +70,6 @@ class Anvil extends Transparent implements Fallable{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8)];
}

View File

@ -87,9 +87,6 @@ class Bamboo extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
//this places the BB at the northwest corner, not the center
$inset = 1 - (($this->thick ? 3 : 2) / 16);

View File

@ -30,7 +30,6 @@ use pocketmine\block\utils\SupportType;
use pocketmine\item\Banner as ItemBanner;
use pocketmine\item\Item;
use pocketmine\item\VanillaItems;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
@ -97,9 +96,6 @@ abstract class BaseBanner extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -34,7 +34,6 @@ use pocketmine\event\block\SignChangeEvent;
use pocketmine\item\Dye;
use pocketmine\item\Item;
use pocketmine\item\ItemTypeIds;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
@ -95,9 +94,6 @@ abstract class BaseSign extends Transparent{
return 16;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -76,9 +76,6 @@ class Bed extends Transparent{
}
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
}

View File

@ -75,7 +75,10 @@ class Block{
protected BlockTypeInfo $typeInfo;
protected Position $position;
/** @var AxisAlignedBB[]|null */
/**
* @var AxisAlignedBB[]|null
* @phpstan-var list<AxisAlignedBB>|null
*/
protected ?array $collisionBoxes = null;
private int $requiredBlockItemStateDataBits;
@ -907,6 +910,7 @@ class Block{
* - anti-cheat checks in plugins
*
* @return AxisAlignedBB[]
* @phpstan-return list<AxisAlignedBB>
*/
final public function getCollisionBoxes() : array{
if($this->collisionBoxes === null){
@ -931,6 +935,7 @@ class Block{
/**
* @return AxisAlignedBB[]
* @phpstan-return list<AxisAlignedBB>
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()];

View File

@ -95,7 +95,7 @@ class BlockBreakInfo{
* Returns whether this block can be instantly broken.
*/
public function breaksInstantly() : bool{
return $this->hardness == 0.0;
return $this->hardness === 0.0;
}
/**
@ -154,7 +154,7 @@ class BlockBreakInfo{
$efficiency = $item->getMiningEfficiency(($this->toolType & $item->getBlockToolType()) !== 0);
if($efficiency <= 0){
throw new \InvalidArgumentException(get_class($item) . " has invalid mining efficiency: expected >= 0, got $efficiency");
throw new \InvalidArgumentException(get_class($item) . " must have a positive mining efficiency, but got $efficiency");
}
$base /= $efficiency;

View File

@ -43,9 +43,6 @@ class Cactus extends Transparent{
return true;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
$shrinkSize = 1 / 16;
return [AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize)];

View File

@ -40,9 +40,6 @@ class Cake extends BaseCake{
$w->boundedIntAuto(0, self::MAX_BITES, $this->bites);
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [
AxisAlignedBB::one()

View File

@ -36,9 +36,6 @@ class CakeWithCandle extends BaseCake{
onInteract as onInteractCandle;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [
AxisAlignedBB::one()

View File

@ -36,9 +36,6 @@ class Carpet extends Flowable{
return true;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 15 / 16)];
}

View File

@ -36,9 +36,6 @@ use pocketmine\player\Player;
class Chest extends Transparent{
use FacesOppositePlacingPlayerTrait;
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
//these are slightly bigger than in PC
return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)];

View File

@ -50,9 +50,6 @@ class CocoaBlock extends Flowable{
$w->boundedIntAuto(0, self::MAX_AGE, $this->age);
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [
AxisAlignedBB::one()

View File

@ -62,9 +62,6 @@ class DaylightSensor extends Transparent{
return 300;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 10 / 16)];
}

View File

@ -95,9 +95,6 @@ class Door extends Transparent{
return false;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
//TODO: doors are 0.1825 blocks thick, instead of 0.1875 like JE (https://bugs.mojang.com/browse/MCPE-19214)
return [AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 327 / 400)];

View File

@ -33,9 +33,6 @@ use pocketmine\player\Player;
class EnchantingTable extends Transparent{
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 0.25)];
}

View File

@ -50,9 +50,6 @@ class EndPortalFrame extends Opaque{
return 1;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 3 / 16)];
}

View File

@ -52,9 +52,6 @@ class EndRod extends Flowable{
return 14;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
$myAxis = Facing::axis($this->facing);

View File

@ -40,9 +40,6 @@ class EnderChest extends Transparent{
return 7;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
//these are slightly bigger than in PC
return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)];

View File

@ -94,9 +94,6 @@ class Farmland extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 16)];
}

View File

@ -54,13 +54,9 @@ class Fence extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
$inset = 0.5 - $this->getThickness() / 2;
/** @var AxisAlignedBB[] $bbs */
$bbs = [];
$connectWest = isset($this->connections[Facing::WEST]);

View File

@ -64,9 +64,6 @@ class FenceGate extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return $this->open ? [] : [AxisAlignedBB::one()->extend(Facing::UP, 0.5)->squash(Facing::axis($this->facing), 6 / 16)];
}

View File

@ -24,7 +24,6 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\block\utils\SupportType;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
/**
@ -46,9 +45,6 @@ abstract class Flowable extends Transparent{
parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock);
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -83,9 +83,6 @@ class FlowerPot extends Flowable{
return $block->hasTypeTag(BlockTypeTags::POTTABLE_PLANTS);
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8)];
}

View File

@ -28,7 +28,6 @@ use pocketmine\block\utils\MultiAnySupportTrait;
use pocketmine\block\utils\SupportType;
use pocketmine\item\Fertilizer;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
@ -47,9 +46,6 @@ class GlowLichen extends Transparent{
return false;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -29,9 +29,6 @@ use pocketmine\math\Facing;
class GrassPath extends Transparent{
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 16)];
}

View File

@ -58,9 +58,6 @@ class Ladder extends Transparent{
return true;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim($this->facing, 13 / 16)];
}

View File

@ -59,9 +59,6 @@ class Lantern extends Transparent{
return $this->lightLevel;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [
AxisAlignedBB::one()

View File

@ -30,7 +30,6 @@ use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\entity\Entity;
use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\utils\Utils;
@ -89,9 +88,6 @@ abstract class Liquid extends Transparent{
return false;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -104,9 +104,6 @@ class MobHead extends Flowable{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
$collisionBox = AxisAlignedBB::one()
->contract(0.25, 0, 0.25)

View File

@ -28,7 +28,6 @@ use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\entity\Entity;
use pocketmine\item\Item;
use pocketmine\math\Axis;
use pocketmine\math\AxisAlignedBB;
class NetherPortal extends Transparent{
@ -62,9 +61,6 @@ class NetherPortal extends Transparent{
return false;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -79,9 +79,6 @@ class RedstoneComparator extends Flowable{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)];
}

View File

@ -62,9 +62,6 @@ class RedstoneRepeater extends Flowable{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)];
}

View File

@ -26,7 +26,6 @@ namespace pocketmine\block;
use pocketmine\block\utils\SupportType;
use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\item\Item;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use pocketmine\world\BlockTransaction;
@ -70,9 +69,6 @@ class SeaPickle extends Transparent{
return $this->underwater ? ($this->count + 1) * 3 : 0;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [];
}

View File

@ -93,9 +93,6 @@ class Slab extends Transparent{
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
if($this->slabType === SlabType::DOUBLE){
return [AxisAlignedBB::one()];

View File

@ -65,9 +65,6 @@ class SnowLayer extends Flowable implements Fallable{
return $this->layers < self::MAX_LAYERS;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
//TODO: this zero-height BB is intended to stay in lockstep with a MCPE bug
return [AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1)];

View File

@ -28,9 +28,6 @@ use pocketmine\math\Facing;
class SoulSand extends Opaque{
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 8)];
}

View File

@ -56,7 +56,6 @@ class Thin extends Transparent{
protected function recalculateCollisionBoxes() : array{
$inset = 7 / 16;
/** @var AxisAlignedBB[] $bbs */
$bbs = [];
if(isset($this->connections[Facing::WEST]) || isset($this->connections[Facing::EAST])){

View File

@ -62,9 +62,6 @@ class Trapdoor extends Transparent{
return $this;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16)];
}

View File

@ -33,9 +33,6 @@ class WaterLily extends Flowable{
canBePlacedAt as supportedWhenPlacedAt;
}
/**
* @return AxisAlignedBB[]
*/
protected function recalculateCollisionBoxes() : array{
return [AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64)];
}

View File

@ -62,9 +62,10 @@ class Sign extends Spawnable{
/**
* @return string[]
* @deprecated
*/
public static function fixTextBlob(string $blob) : array{
return array_slice(array_pad(explode("\n", $blob), 4, ""), 0, 4);
return array_slice(array_pad(explode("\n", $blob, limit: 5), 4, ""), 0, 4);
}
protected SignText $text;

View File

@ -43,7 +43,10 @@ trait CandleTrait{
return $this->lit ? 3 : 0;
}
/** @see Block::onInteract() */
/**
* @param Item[] &$returnedItems
* @see Block::onInteract()
*/
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($item->getTypeId() === ItemTypeIds::FIRE_CHARGE || $item->getTypeId() === ItemTypeIds::FLINT_AND_STEEL || $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){
if($this->lit){

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\block\Block;
use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\item\Axe;
use pocketmine\item\Item;
@ -58,6 +59,10 @@ trait CopperTrait{
return $this;
}
/**
* @param Item[] &$returnedItems
* @see Block::onInteract()
*/
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if(!$this->waxed && $item->getTypeId() === ItemTypeIds::HONEYCOMB){
$this->waxed = true;

View File

@ -79,7 +79,7 @@ class SignText{
* @throws \InvalidArgumentException if the text is not valid UTF-8
*/
public static function fromBlob(string $blob, ?Color $baseColor = null, bool $glowing = false) : SignText{
return new self(array_slice(array_pad(explode("\n", $blob), self::LINE_COUNT, ""), 0, self::LINE_COUNT), $baseColor, $glowing);
return new self(array_slice(array_pad(explode("\n", $blob, limit: self::LINE_COUNT + 1), self::LINE_COUNT, ""), 0, self::LINE_COUNT), $baseColor, $glowing);
}
/**

View File

@ -33,9 +33,11 @@ use pocketmine\permission\PermissionManager;
use pocketmine\Server;
use pocketmine\utils\BroadcastLoggerForwarder;
use pocketmine\utils\TextFormat;
use function array_values;
use function explode;
use function implode;
use function str_replace;
use const PHP_INT_MAX;
abstract class Command{
@ -80,6 +82,7 @@ abstract class Command{
/**
* @param string[] $args
* @phpstan-param list<string> $args
*
* @return mixed
* @throws CommandException
@ -111,7 +114,7 @@ abstract class Command{
}
public function setPermission(?string $permission) : void{
$this->setPermissions($permission === null ? [] : explode(";", $permission));
$this->setPermissions($permission === null ? [] : explode(";", $permission, limit: PHP_INT_MAX));
}
public function testPermission(CommandSender $target, ?string $permission = null) : bool{
@ -212,6 +215,7 @@ abstract class Command{
* @phpstan-param list<string> $aliases
*/
public function setAliases(array $aliases) : void{
$aliases = array_values($aliases); //because plugins can and will pass crap
$this->aliases = $aliases;
if(!$this->isRegistered()){
$this->activeAliases = $aliases;

View File

@ -121,6 +121,7 @@ class FormattedCommandAlias extends Command{
/**
* @param string[] $args
* @phpstan-param list<string> $args
*/
private function buildCommand(string $formatString, array $args) : ?string{
$index = 0;

View File

@ -73,6 +73,7 @@ use pocketmine\timings\Timings;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use function array_shift;
use function array_values;
use function count;
use function implode;
use function str_contains;
@ -163,7 +164,7 @@ class SimpleCommandMap implements CommandMap{
unset($aliases[$index]);
}
}
$command->setAliases($aliases);
$command->setAliases(array_values($aliases));
if(!$registered){
$command->setLabel($fallbackPrefix . ":" . $label);

View File

@ -39,6 +39,7 @@ use function ksort;
use function min;
use function sort;
use function strtolower;
use const PHP_INT_MAX;
use const SORT_FLAG_CASE;
use const SORT_NATURAL;
@ -108,7 +109,7 @@ class HelpCommand extends VanillaCommand{
$usage = $cmd->getUsage();
$usageString = $usage instanceof Translatable ? $lang->translate($usage) : $usage;
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::RESET . implode("\n" . TextFormat::RESET, explode("\n", $usageString)))
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::RESET . implode("\n" . TextFormat::RESET, explode("\n", $usageString, limit: PHP_INT_MAX)))
->prefix(TextFormat::GOLD));
$aliases = $cmd->getAliases();

View File

@ -219,7 +219,11 @@ class ParticleCommand extends VanillaCommand{
break;
case "blockdust":
if($data !== null){
$d = explode("_", $data);
//to preserve the old unlimited explode behaviour, allow this to split into at most 5 parts
//this allows the 4th argument to be processed normally if given without forcing it to also consume
//any unexpected parts
//we probably ought to error in this case, but this will do for now
$d = explode("_", $data, limit: 5);
if(count($d) >= 3){
return new DustParticle(new Color(
((int) $d[0]) & 0xff,

View File

@ -46,6 +46,8 @@ use function fwrite;
use function http_build_query;
use function implode;
use function is_array;
use function is_int;
use function is_string;
use function json_decode;
use function mkdir;
use function strtolower;
@ -178,7 +180,7 @@ class TimingsCommand extends VanillaCommand{
return;
}
$response = json_decode($result->getBody(), true);
if(is_array($response) && isset($response["id"])){
if(is_array($response) && isset($response["id"]) && (is_int($response["id"]) || is_string($response["id"]))){
Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsRead(
"https://" . $host . "/?id=" . $response["id"]));
}else{

View File

@ -51,9 +51,8 @@ final class CommandStringHelper{
foreach($matches[0] as $k => $_){
for($i = 1; $i <= 2; ++$i){
if($matches[$i][$k] !== ""){
/** @var string $match */ //phpstan can't understand preg_match and friends by itself :(
$match = $matches[$i][$k];
$args[(int) $k] = preg_replace('/\\\\([\\\\"])/u', '$1', $match) ?? throw new AssumptionFailedError(preg_last_error_msg());
$args[] = preg_replace('/\\\\([\\\\"])/u', '$1', $match) ?? throw new AssumptionFailedError(preg_last_error_msg());
break;
}
}

View File

@ -62,7 +62,7 @@ class ConsoleCommandSender implements CommandSender{
$message = $this->getLanguage()->translate($message);
}
foreach(explode("\n", trim($message)) as $line){
foreach(explode("\n", trim($message), limit: PHP_INT_MAX) as $line){
Terminal::writeLine(TextFormat::GREEN . "Command output | " . TextFormat::addBase(TextFormat::WHITE, $line));
}
}

View File

@ -110,7 +110,6 @@ class CraftingManager{
/**
* @param Item[] $items
* @phpstan-param list<Item> $items
*
* @return Item[]
* @phpstan-return list<Item>
@ -135,7 +134,6 @@ class CraftingManager{
/**
* @param Item[] $outputs
* @phpstan-param list<Item> $outputs
*/
private static function hashOutputs(array $outputs) : string{
$outputs = self::pack($outputs);

View File

@ -97,6 +97,7 @@ class ShapedRecipe implements CraftingRecipe{
$this->shape = $shape;
Utils::validateArrayValueType($ingredients, function(RecipeIngredient $_) : void{});
foreach(Utils::stringifyKeys($ingredients) as $char => $i){
if(!str_contains(implode($this->shape), $char)){
throw new \InvalidArgumentException("Symbol '$char' does not appear in the recipe shape");
@ -105,6 +106,7 @@ class ShapedRecipe implements CraftingRecipe{
$this->ingredientList[$char] = clone $i;
}
Utils::validateArrayValueType($results, function(Item $_) : void{});
$this->results = Utils::cloneObjectArray($results);
}

View File

@ -53,7 +53,9 @@ class ShapelessRecipe implements CraftingRecipe{
if(count($ingredients) > 9){
throw new \InvalidArgumentException("Shapeless recipes cannot have more than 9 ingredients");
}
Utils::validateArrayValueType($ingredients, function(RecipeIngredient $_) : void{});
$this->ingredients = $ingredients;
Utils::validateArrayValueType($results, function(Item $_) : void{});
$this->results = Utils::cloneObjectArray($results);
}

View File

@ -39,14 +39,16 @@ final class BedrockDataFiles{
public const BLOCK_STATE_META_MAP_JSON = BEDROCK_DATA_PATH . '/block_state_meta_map.json';
public const CANONICAL_BLOCK_STATES_NBT = BEDROCK_DATA_PATH . '/canonical_block_states.nbt';
public const COMMAND_ARG_TYPES_JSON = BEDROCK_DATA_PATH . '/command_arg_types.json';
public const CREATIVEITEMS_JSON = BEDROCK_DATA_PATH . '/creativeitems.json';
public const CREATIVE = BEDROCK_DATA_PATH . '/creative';
public const ENTITY_ID_MAP_JSON = BEDROCK_DATA_PATH . '/entity_id_map.json';
public const ENTITY_IDENTIFIERS_NBT = BEDROCK_DATA_PATH . '/entity_identifiers.nbt';
public const ENUMS = BEDROCK_DATA_PATH . '/enums';
public const ENUMS_PY = BEDROCK_DATA_PATH . '/enums.py';
public const ITEM_TAGS_JSON = BEDROCK_DATA_PATH . '/item_tags.json';
public const LEVEL_SOUND_ID_MAP_JSON = BEDROCK_DATA_PATH . '/level_sound_id_map.json';
public const PARTICLE_ID_MAP_JSON = BEDROCK_DATA_PATH . '/particle_id_map.json';
public const PROTOCOL_INFO_JSON = BEDROCK_DATA_PATH . '/protocol_info.json';
public const R12_TO_CURRENT_BLOCK_MAP_BIN = BEDROCK_DATA_PATH . '/r12_to_current_block_map.bin';
public const R16_TO_CURRENT_ITEM_MAP_JSON = BEDROCK_DATA_PATH . '/r16_to_current_item_map.json';
public const RECIPES = BEDROCK_DATA_PATH . '/recipes';
public const REQUIRED_ITEM_LIST_JSON = BEDROCK_DATA_PATH . '/required_item_list.json';
}

View File

@ -39,10 +39,10 @@ final class NoteInstrumentIdMap{
NoteInstrument::SNARE => 2,
NoteInstrument::CLICKS_AND_STICKS => 3,
NoteInstrument::DOUBLE_BASS => 4,
NoteInstrument::BELL => 5,
NoteInstrument::FLUTE => 6,
NoteInstrument::CHIME => 7,
NoteInstrument::GUITAR => 8,
NoteInstrument::FLUTE => 5,
NoteInstrument::BELL => 6,
NoteInstrument::GUITAR => 7,
NoteInstrument::CHIME => 8,
NoteInstrument::XYLOPHONE => 9,
NoteInstrument::IRON_XYLOPHONE => 10,
NoteInstrument::COW_BELL => 11,

View File

@ -45,8 +45,8 @@ final class BlockStateData{
public const CURRENT_VERSION =
(1 << 24) | //major
(21 << 16) | //minor
(40 << 8) | //patch
(1); //revision
(60 << 8) | //patch
(33); //revision
public const TAG_NAME = "name";
public const TAG_STATES = "states";

View File

@ -59,6 +59,7 @@ final class BlockStateNames{
public const COVERED_BIT = "covered_bit";
public const CRACKED_STATE = "cracked_state";
public const CRAFTING = "crafting";
public const CREAKING_HEART_STATE = "creaking_heart_state";
public const DEAD_BIT = "dead_bit";
public const DEPRECATED = "deprecated";
public const DIRECTION = "direction";

View File

@ -56,6 +56,10 @@ final class BlockStateStringValues{
public const CRACKED_STATE_MAX_CRACKED = "max_cracked";
public const CRACKED_STATE_NO_CRACKS = "no_cracks";
public const CREAKING_HEART_STATE_AWAKE = "awake";
public const CREAKING_HEART_STATE_DORMANT = "dormant";
public const CREAKING_HEART_STATE_UPROOTED = "uprooted";
public const DRIPSTONE_THICKNESS_BASE = "base";
public const DRIPSTONE_THICKNESS_FRUSTUM = "frustum";
public const DRIPSTONE_THICKNESS_MERGE = "merge";

View File

@ -131,7 +131,8 @@ final class BlockStateDeserializerHelper{
//TODO: check if these need any special treatment to get the appropriate data to both halves of the door
return $block
->setTop($in->readBool(BlockStateNames::UPPER_BLOCK_BIT))
->setFacing(Facing::rotateY($in->readLegacyHorizontalFacing(), false))
//a door facing "east" is actually facing north - thanks mojang
->setFacing(Facing::rotateY($in->readCardinalHorizontalFacing(), clockwise: false))
->setHingeRight($in->readBool(BlockStateNames::DOOR_HINGE_BIT))
->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
}
@ -145,7 +146,7 @@ final class BlockStateDeserializerHelper{
/** @throws BlockStateDeserializeException */
public static function decodeFenceGate(FenceGate $block, BlockStateReader $in) : FenceGate{
return $block
->setFacing($in->readLegacyHorizontalFacing())
->setFacing($in->readCardinalHorizontalFacing())
->setInWall($in->readBool(BlockStateNames::IN_WALL_BIT))
->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
}

View File

@ -100,7 +100,8 @@ final class BlockStateSerializerHelper{
public static function encodeDoor(Door $block, Writer $out) : Writer{
return $out
->writeBool(BlockStateNames::UPPER_BLOCK_BIT, $block->isTop())
->writeLegacyHorizontalFacing(Facing::rotateY($block->getFacing(), true))
//a door facing north is encoded as "east"
->writeCardinalHorizontalFacing(Facing::rotateY($block->getFacing(), clockwise: true))
->writeBool(BlockStateNames::DOOR_HINGE_BIT, $block->isHingeRight())
->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen());
}
@ -112,7 +113,7 @@ final class BlockStateSerializerHelper{
public static function encodeFenceGate(FenceGate $block, Writer $out) : Writer{
return $out
->writeLegacyHorizontalFacing($block->getFacing())
->writeCardinalHorizontalFacing($block->getFacing())
->writeBool(BlockStateNames::IN_WALL_BIT, $block->isInWall())
->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen());
}

View File

@ -37,7 +37,6 @@ use pocketmine\utils\Utils;
use Symfony\Component\Filesystem\Path;
use function array_key_last;
use function array_map;
use function array_values;
use function assert;
use function count;
use function get_debug_type;
@ -138,8 +137,8 @@ final class BlockStateUpgradeSchemaUtils{
$convertedRemappedValuesIndex = [];
foreach(Utils::stringifyKeys($model->remappedPropertyValuesIndex ?? []) as $mappingKey => $mappingValues){
foreach($mappingValues as $k => $oldNew){
$convertedRemappedValuesIndex[$mappingKey][$k] = new BlockStateUpgradeSchemaValueRemap(
foreach($mappingValues as $oldNew){
$convertedRemappedValuesIndex[$mappingKey][] = new BlockStateUpgradeSchemaValueRemap(
self::jsonModelToTag($oldNew->old),
self::jsonModelToTag($oldNew->new)
);
@ -361,7 +360,7 @@ final class BlockStateUpgradeSchemaUtils{
//remaps with the same number of criteria should be sorted alphabetically, but this is not strictly necessary
return json_encode($a->oldState ?? []) <=> json_encode($b->oldState ?? []);
});
$result->remappedStates[$oldBlockName] = array_values($keyedRemaps);
$result->remappedStates[$oldBlockName] = $keyedRemaps; //usort strips keys, so this is already a list
}
if(isset($result->remappedStates)){
ksort($result->remappedStates);

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\data\runtime;
use function array_values;
use function ceil;
use function count;
use function log;
@ -60,7 +59,7 @@ final class RuntimeEnumMetadata{
usort($members, fn(\UnitEnum $a, \UnitEnum $b) => $a->name <=> $b->name); //sort by name to ensure consistent ordering (and thus consistent bit assignments)
$this->bits = (int) ceil(log(count($members), 2));
$this->intToEnum = array_values($members);
$this->intToEnum = $members; //usort strips keys so this is already a list
$reversed = [];
foreach($this->intToEnum as $int => $enum){

View File

@ -76,7 +76,7 @@ class Attribute{
throw new \InvalidArgumentException("Minimum $minValue is greater than the maximum $max");
}
if($this->minValue != $minValue){
if($this->minValue !== $minValue){
$this->desynchronized = true;
$this->minValue = $minValue;
}
@ -95,7 +95,7 @@ class Attribute{
throw new \InvalidArgumentException("Maximum $maxValue is less than the minimum $min");
}
if($this->maxValue != $maxValue){
if($this->maxValue !== $maxValue){
$this->desynchronized = true;
$this->maxValue = $maxValue;
}
@ -140,7 +140,7 @@ class Attribute{
$value = min(max($value, $this->getMinValue()), $this->getMaxValue());
}
if($this->currentValue != $value){
if($this->currentValue !== $value){
$this->desynchronized = true;
$this->currentValue = $value;
}elseif($forceSend){

View File

@ -72,6 +72,7 @@ use function assert;
use function cos;
use function count;
use function deg2rad;
use function floatval;
use function floor;
use function fmod;
use function get_class;
@ -591,7 +592,7 @@ abstract class Entity{
* Sets the health of the Entity. This won't send any update to the players
*/
public function setHealth(float $amount) : void{
if($amount == $this->health){
if($amount === $this->health){
return;
}
@ -760,8 +761,8 @@ abstract class Entity{
$diffMotion = $this->motion->subtractVector($this->lastMotion)->lengthSquared();
$still = $this->motion->lengthSquared() == 0.0;
$wasStill = $this->lastMotion->lengthSquared() == 0.0;
$still = $this->motion->lengthSquared() === 0.0;
$wasStill = $this->lastMotion->lengthSquared() === 0.0;
if($wasStill !== $still){
//TODO: hack for client-side AI interference: prevent client sided movement when motion is 0
$this->setNoClientPredictions($still);
@ -1004,7 +1005,7 @@ abstract class Entity{
abs($this->motion->z) <= self::MOTION_THRESHOLD ? 0 : null
);
if($this->motion->x != 0 || $this->motion->y != 0 || $this->motion->z != 0){
if(floatval($this->motion->x) !== 0.0 || floatval($this->motion->y) !== 0.0 || floatval($this->motion->z) !== 0.0){
$this->move($this->motion->x, $this->motion->y, $this->motion->z);
}
@ -1058,9 +1059,9 @@ abstract class Entity{
public function hasMovementUpdate() : bool{
return (
$this->forceMovementUpdate ||
$this->motion->x != 0 ||
$this->motion->y != 0 ||
$this->motion->z != 0 ||
floatval($this->motion->x) !== 0.0 ||
floatval($this->motion->y) !== 0.0 ||
floatval($this->motion->z) !== 0.0 ||
!$this->onGround
);
}
@ -1163,7 +1164,7 @@ abstract class Entity{
$moveBB->offset(0, $dy, 0);
$fallingFlag = ($this->onGround || ($dy != $wantedY && $wantedY < 0));
$fallingFlag = ($this->onGround || ($dy !== $wantedY && $wantedY < 0));
foreach($list as $bb){
$dx = $bb->calculateXOffset($moveBB, $dx);
@ -1177,7 +1178,7 @@ abstract class Entity{
$moveBB->offset(0, 0, $dz);
if($this->stepHeight > 0 && $fallingFlag && ($wantedX != $dx || $wantedZ != $dz)){
if($this->stepHeight > 0 && $fallingFlag && ($wantedX !== $dx || $wantedZ !== $dz)){
$cx = $dx;
$cy = $dy;
$cz = $dz;
@ -1242,9 +1243,9 @@ abstract class Entity{
$postFallVerticalVelocity = $this->updateFallState($dy, $this->onGround);
$this->motion = $this->motion->withComponents(
$wantedX != $dx ? 0 : null,
$postFallVerticalVelocity ?? ($wantedY != $dy ? 0 : null),
$wantedZ != $dz ? 0 : null
$wantedX !== $dx ? 0 : null,
$postFallVerticalVelocity ?? ($wantedY !== $dy ? 0 : null),
$wantedZ !== $dz ? 0 : null
);
//TODO: vehicle collision events (first we need to spawn them!)
@ -1253,10 +1254,10 @@ abstract class Entity{
}
protected function checkGroundState(float $wantedX, float $wantedY, float $wantedZ, float $dx, float $dy, float $dz) : void{
$this->isCollidedVertically = $wantedY != $dy;
$this->isCollidedHorizontally = ($wantedX != $dx || $wantedZ != $dz);
$this->isCollidedVertically = $wantedY !== $dy;
$this->isCollidedHorizontally = ($wantedX !== $dx || $wantedZ !== $dz);
$this->isCollided = ($this->isCollidedHorizontally || $this->isCollidedVertically);
$this->onGround = ($wantedY != $dy && $wantedY < 0);
$this->onGround = ($wantedY !== $dy && $wantedY < 0);
}
/**
@ -1494,7 +1495,7 @@ abstract class Entity{
$this->getId(), //TODO: actor unique ID
$this->getId(),
static::getNetworkTypeId(),
$this->location->asVector3(),
$this->getOffsetPosition($this->location->asVector3()),
$this->getMotion(),
$this->location->pitch,
$this->location->yaw,

View File

@ -513,6 +513,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
AbilitiesLayer::LAYER_BASE,
array_fill(0, AbilitiesLayer::NUMBER_OF_ABILITIES, false),
0.0,
0.0,
0.0
)
])),

View File

@ -66,7 +66,7 @@ class Location extends Position{
public function equals(Vector3 $v) : bool{
if($v instanceof Location){
return parent::equals($v) && $v->yaw == $this->yaw && $v->pitch == $this->pitch;
return parent::equals($v) && $v->yaw === $this->yaw && $v->pitch === $this->pitch;
}
return parent::equals($v);
}

View File

@ -44,7 +44,6 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\timings\Timings;
use function assert;
use function atan2;
use function ceil;
use function count;
@ -170,8 +169,6 @@ abstract class Projectile extends Entity{
$start = $this->location->asVector3();
$end = $start->add($dx, $dy, $dz);
$blockHit = null;
$entityHit = null;
$hitResult = null;
$world = $this->getWorld();
@ -181,8 +178,7 @@ abstract class Projectile extends Entity{
$blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end);
if($blockHitResult !== null){
$end = $blockHitResult->hitVector;
$blockHit = $block;
$hitResult = $blockHitResult;
$hitResult = [$block, $blockHitResult];
break;
}
}
@ -206,8 +202,7 @@ abstract class Projectile extends Entity{
if($distance < $entityDistance){
$entityDistance = $distance;
$entityHit = $entity;
$hitResult = $entityHitResult;
$hitResult = [$entity, $entityHitResult];
$end = $entityHitResult->hitVector;
}
}
@ -223,26 +218,18 @@ abstract class Projectile extends Entity{
$this->recalculateBoundingBox();
if($hitResult !== null){
/** @var ProjectileHitEvent|null $ev */
$ev = null;
if($entityHit !== null){
$ev = new ProjectileHitEntityEvent($this, $hitResult, $entityHit);
}elseif($blockHit !== null){
$ev = new ProjectileHitBlockEvent($this, $hitResult, $blockHit);
[$objectHit, $rayTraceResult] = $hitResult;
if($objectHit instanceof Entity){
$ev = new ProjectileHitEntityEvent($this, $rayTraceResult, $objectHit);
$specificHitFunc = fn() => $this->onHitEntity($objectHit, $rayTraceResult);
}else{
assert(false, "unknown hit type");
$ev = new ProjectileHitBlockEvent($this, $rayTraceResult, $objectHit);
$specificHitFunc = fn() => $this->onHitBlock($objectHit, $rayTraceResult);
}
if($ev !== null){
$ev->call();
$this->onHit($ev);
if($ev instanceof ProjectileHitEntityEvent){
$this->onHitEntity($ev->getEntityHit(), $ev->getRayTraceResult());
}elseif($ev instanceof ProjectileHitBlockEvent){
$this->onHitBlock($ev->getBlockHit(), $ev->getRayTraceResult());
}
}
$ev->call();
$this->onHit($ev);
$specificHitFunc();
$this->isCollided = $this->onGround = true;
$this->motion = Vector3::zero();
@ -290,10 +277,11 @@ abstract class Projectile extends Entity{
$damage = $this->getResultDamage();
if($damage >= 0){
if($this->getOwningEntity() === null){
$owner = $this->getOwningEntity();
if($owner === null){
$ev = new EntityDamageByEntityEvent($this, $entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}else{
$ev = new EntityDamageByChildEntityEvent($this->getOwningEntity(), $this, $entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
$ev = new EntityDamageByChildEntityEvent($owner, $this, $entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
}
$entityHit->attack($ev);

View File

@ -119,7 +119,7 @@ class HandlerListManager{
public function getHandlersFor(string $event) : array{
$cache = $this->handlerCaches[$event] ?? null;
//getListFor() will populate the cache for the next call
return $cache?->list ?? $this->getListFor($event)->getListenerList();
return $cache->list ?? $this->getListFor($event)->getListenerList();
}
/**

View File

@ -52,9 +52,15 @@ class PlayerPreLoginEvent extends Event{
self::KICK_FLAG_BANNED
];
/** @var Translatable[]|string[] reason const => associated message */
/**
* @var Translatable[]|string[] reason const => associated message
* @phpstan-var array<int, Translatable|string>
*/
protected array $disconnectReasons = [];
/** @var Translatable[]|string[] */
/**
* @var Translatable[]|string[]
* @phpstan-var array<int, Translatable|string>
*/
protected array $disconnectScreenMessages = [];
public function __construct(
@ -93,6 +99,7 @@ class PlayerPreLoginEvent extends Event{
* Returns an array of kick flags currently assigned.
*
* @return int[]
* @phpstan-return list<int>
*/
public function getKickFlags() : array{
return array_keys($this->disconnectReasons);

View File

@ -0,0 +1,34 @@
<?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\inventory;
/**
* Available tabs in the creative inventory that an item can be displayed in.
*/
enum CreativeCategory{
case CONSTRUCTION;
case NATURE;
case EQUIPMENT;
case ITEMS;
}

Some files were not shown because too many files have changed in this diff Show More