mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-09 19:24:12 +00:00
Compare commits
78 Commits
experiment
...
5.25.0
Author | SHA1 | Date | |
---|---|---|---|
d96ef21c4d | |||
03e4b53ac4 | |||
91ac64783f | |||
9402a20ee3 | |||
5ef89200c6 | |||
39e69276a1 | |||
94797e3afa | |||
9d6a0cc738 | |||
07987890a0 | |||
f60120a75e | |||
fc86d3a44e | |||
393d7f72a9 | |||
b625fee94b | |||
6b606dca95 | |||
406ddf3e53 | |||
ec6077776a | |||
f7b5cd7ff3 | |||
3453ff03fd | |||
04e63172c3 | |||
51cb1875bb | |||
0b60a47cde | |||
d1066d0199 | |||
f349ce75e4 | |||
b3f15435cc | |||
847ae26cad | |||
d42ec06647 | |||
5e0f03dff0 | |||
4a83920db9 | |||
0a16daa619 | |||
e34f34f9f4 | |||
e8c4b743b5 | |||
689a7996b9 | |||
794641c0f8 | |||
9633b7d8a7 | |||
d25ec58a6f | |||
d69a887b0d | |||
38441a6ba3 | |||
47cb04f6a6 | |||
b1c7fc017a | |||
cd59e272bc | |||
7b1b35ab1f | |||
28d31c97f8 | |||
a17512de93 | |||
601be3fb33 | |||
2e32c50670 | |||
d1fa6edc50 | |||
a1ba8bc3da | |||
73edb8799d | |||
9592f066f3 | |||
db9ba83001 | |||
1b2d2a3fe1 | |||
84ec8b7abe | |||
357dfb5c7e | |||
0358b7dce4 | |||
97c5902ae2 | |||
9a130bce32 | |||
20849d6268 | |||
b6bd3ef30c | |||
c5a1c15389 | |||
e30ae487dc | |||
59f6c85105 | |||
90f0b85d2e | |||
8ee70b209e | |||
5c905d9a95 | |||
8b23231537 | |||
8e039f2711 | |||
4a4572131f | |||
3da0b82b86 | |||
da62eb9f33 | |||
09c434983b | |||
fbaa125d0c | |||
6ad9dde43d | |||
d634a5fa3d | |||
8cea4c13c4 | |||
dc2e82df7f | |||
debf8d18fc | |||
81e3730b99 | |||
8a5eb71432 |
19
.github/ISSUE_TEMPLATE/api-change-request.md
vendored
19
.github/ISSUE_TEMPLATE/api-change-request.md
vendored
@ -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
84
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal 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
|
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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 -->
|
16
.github/ISSUE_TEMPLATE/crash.md
vendored
16
.github/ISSUE_TEMPLATE/crash.md
vendored
@ -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
25
.github/ISSUE_TEMPLATE/crash.yml
vendored
Normal 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
|
19
.github/ISSUE_TEMPLATE/feature-proposal.yml
vendored
Normal file
19
.github/ISSUE_TEMPLATE/feature-proposal.yml
vendored
Normal 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"
|
8
.github/workflows/build-docker-image.yml
vendored
8
.github/workflows/build-docker-image.yml
vendored
@ -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.13.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.13.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.13.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.13.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
|
2
.github/workflows/discord-release-notify.yml
vendored
2
.github/workflows/discord-release-notify.yml
vendored
@ -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
|
||||
|
||||
|
2
.github/workflows/draft-release-pr-check.yml
vendored
2
.github/workflows/draft-release-pr-check.yml
vendored
@ -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
|
||||
|
||||
|
4
.github/workflows/draft-release.yml
vendored
4
.github/workflows/draft-release.yml
vendored
@ -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.15.0
|
||||
id: create-draft
|
||||
with:
|
||||
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json,${{ github.workspace }}/core-permissions.rst
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -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
|
||||
|
@ -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;
|
||||
|
Submodule build/php updated: b1eaaa48ec...1549433797
@ -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);
|
||||
}
|
||||
|
@ -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
108
changelogs/5.24.md
Normal 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.
|
38
changelogs/5.25.md
Normal file
38
changelogs/5.25.md
Normal file
@ -0,0 +1,38 @@
|
||||
# 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.
|
@ -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/bedrock-protocol": "~36.0.0+bedrock-1.21.60",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"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.4",
|
||||
"phpstan/phpstan-phpunit": "^2.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^2.0.0",
|
||||
"phpunit/phpunit": "^10.5.24"
|
||||
},
|
||||
"autoload": {
|
||||
|
164
composer.lock
generated
164
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "732102eca72dc1d29e7b67dfbce07653",
|
||||
"content-hash": "af7547291a131bfac6d7087957601325",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -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,9 +296,9 @@
|
||||
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockProtocol/issues",
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/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",
|
||||
@ -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": {
|
||||
@ -1210,16 +1210,16 @@
|
||||
},
|
||||
{
|
||||
"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.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3"
|
||||
"reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3",
|
||||
"reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f99e18eb775dbaf6460c95fa0b65312da9c746a",
|
||||
"reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a",
|
||||
"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-10T08:25:21+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.44",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132"
|
||||
"reference": "1381c62769be4bb88fa4c5aec1366c7c66ca4f36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132",
|
||||
"reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1381c62769be4bb88fa4c5aec1366c7c66ca4f36",
|
||||
"reference": "1381c62769be4bb88fa4c5aec1366c7c66ca4f36",
|
||||
"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.44"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1963,7 +1961,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-28T13:06:21+00:00"
|
||||
"time": "2025-01-31T07:00:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
@ -19,6 +19,7 @@ rules:
|
||||
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 +32,7 @@ parameters:
|
||||
paths:
|
||||
- build
|
||||
- src
|
||||
- tests/phpstan/DummyPluginOwned.php
|
||||
- tests/phpstan/rules
|
||||
- tests/phpunit
|
||||
- tests/plugins/TesterPlugin
|
||||
@ -44,6 +46,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
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
@ -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");
|
||||
|
@ -31,8 +31,8 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "5.23.3";
|
||||
public const IS_DEVELOPMENT_BUILD = true;
|
||||
public const BASE_VERSION = "5.25.0";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
/**
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -76,9 +76,6 @@ class Bed extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
|
||||
}
|
||||
|
@ -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()];
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)];
|
||||
|
@ -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()
|
||||
|
@ -36,9 +36,6 @@ class CakeWithCandle extends BaseCake{
|
||||
onInteract as onInteractCandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
AxisAlignedBB::one()
|
||||
|
@ -36,9 +36,6 @@ class Carpet extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 15 / 16)];
|
||||
}
|
||||
|
@ -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)];
|
||||
|
@ -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()
|
||||
|
@ -62,9 +62,6 @@ class DaylightSensor extends Transparent{
|
||||
return 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 10 / 16)];
|
||||
}
|
||||
|
@ -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)];
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -50,9 +50,6 @@ class EndPortalFrame extends Opaque{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 3 / 16)];
|
||||
}
|
||||
|
@ -52,9 +52,6 @@ class EndRod extends Flowable{
|
||||
return 14;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$myAxis = Facing::axis($this->facing);
|
||||
|
||||
|
@ -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)];
|
||||
|
@ -94,9 +94,6 @@ class Farmland extends Transparent{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 16)];
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -58,9 +58,6 @@ class Ladder extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim($this->facing, 13 / 16)];
|
||||
}
|
||||
|
@ -59,9 +59,6 @@ class Lantern extends Transparent{
|
||||
return $this->lightLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
AxisAlignedBB::one()
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -79,9 +79,6 @@ class RedstoneComparator extends Flowable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)];
|
||||
}
|
||||
|
@ -62,9 +62,6 @@ class RedstoneRepeater extends Flowable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)];
|
||||
}
|
||||
|
@ -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 [];
|
||||
}
|
||||
|
@ -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()];
|
||||
|
@ -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)];
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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])){
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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)];
|
||||
}
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
@ -33,6 +33,7 @@ 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;
|
||||
@ -80,6 +81,7 @@ abstract class Command{
|
||||
|
||||
/**
|
||||
* @param string[] $args
|
||||
* @phpstan-param list<string> $args
|
||||
*
|
||||
* @return mixed
|
||||
* @throws CommandException
|
||||
@ -212,6 +214,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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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';
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -131,7 +131,7 @@ 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))
|
||||
->setFacing($in->readCardinalHorizontalFacing())
|
||||
->setHingeRight($in->readBool(BlockStateNames::DOOR_HINGE_BIT))
|
||||
->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
|
||||
}
|
||||
@ -145,7 +145,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));
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ 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))
|
||||
->writeCardinalHorizontalFacing($block->getFacing())
|
||||
->writeBool(BlockStateNames::DOOR_HINGE_BIT, $block->isHingeRight())
|
||||
->writeBool(BlockStateNames::OPEN_BIT, $block->isOpen());
|
||||
}
|
||||
@ -112,7 +112,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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
)
|
||||
])),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
34
src/inventory/CreativeCategory.php
Normal file
34
src/inventory/CreativeCategory.php
Normal 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;
|
||||
}
|
51
src/inventory/CreativeGroup.php
Normal file
51
src/inventory/CreativeGroup.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?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;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\lang\Translatable;
|
||||
use function strlen;
|
||||
|
||||
/**
|
||||
* Info for an item group in the creative inventory menu.
|
||||
*/
|
||||
final class CreativeGroup{
|
||||
/**
|
||||
* @param Translatable|string $name Tooltip shown to the player on hover
|
||||
* @param Item $icon Item shown when the group is collapsed
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly Translatable|string $name,
|
||||
private readonly Item $icon
|
||||
){
|
||||
$nameLength = $name instanceof Translatable ? strlen($name->getText()) : strlen($name);
|
||||
if($nameLength === 0){
|
||||
throw new \InvalidArgumentException("Creative group name cannot be empty");
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() : Translatable|string{ return $this->name; }
|
||||
|
||||
public function getIcon() : Item{ return clone $this->icon; }
|
||||
}
|
@ -24,21 +24,24 @@ declare(strict_types=1);
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\crafting\CraftingManagerFromDataHelper;
|
||||
use pocketmine\crafting\json\ItemStackData;
|
||||
use pocketmine\data\bedrock\BedrockDataFiles;
|
||||
use pocketmine\inventory\json\CreativeGroupData;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\lang\Translatable;
|
||||
use pocketmine\utils\DestructorCallbackTrait;
|
||||
use pocketmine\utils\ObjectSet;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\utils\Utils;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
|
||||
final class CreativeInventory{
|
||||
use SingletonTrait;
|
||||
use DestructorCallbackTrait;
|
||||
|
||||
/**
|
||||
* @var Item[]
|
||||
* @phpstan-var array<int, Item>
|
||||
* @var CreativeInventoryEntry[]
|
||||
* @phpstan-var array<int, CreativeInventoryEntry>
|
||||
*/
|
||||
private array $creative = [];
|
||||
|
||||
@ -47,17 +50,32 @@ final class CreativeInventory{
|
||||
|
||||
private function __construct(){
|
||||
$this->contentChangedCallbacks = new ObjectSet();
|
||||
$creativeItems = CraftingManagerFromDataHelper::loadJsonArrayOfObjectsFile(
|
||||
BedrockDataFiles::CREATIVEITEMS_JSON,
|
||||
ItemStackData::class
|
||||
);
|
||||
foreach($creativeItems as $data){
|
||||
$item = CraftingManagerFromDataHelper::deserializeItemStack($data);
|
||||
if($item === null){
|
||||
//unknown item
|
||||
continue;
|
||||
|
||||
foreach([
|
||||
"construction" => CreativeCategory::CONSTRUCTION,
|
||||
"nature" => CreativeCategory::NATURE,
|
||||
"equipment" => CreativeCategory::EQUIPMENT,
|
||||
"items" => CreativeCategory::ITEMS,
|
||||
] as $categoryId => $categoryEnum){
|
||||
$groups = CraftingManagerFromDataHelper::loadJsonArrayOfObjectsFile(
|
||||
Path::join(BedrockDataFiles::CREATIVE, $categoryId . ".json"),
|
||||
CreativeGroupData::class
|
||||
);
|
||||
|
||||
foreach($groups as $groupData){
|
||||
$icon = $groupData->group_icon === null ? null : CraftingManagerFromDataHelper::deserializeItemStack($groupData->group_icon);
|
||||
|
||||
$group = $icon === null ? null : new CreativeGroup(
|
||||
new Translatable($groupData->group_name),
|
||||
$icon
|
||||
);
|
||||
|
||||
$items = array_filter(array_map(static fn($itemStack) => CraftingManagerFromDataHelper::deserializeItemStack($itemStack), $groupData->items));
|
||||
|
||||
foreach($items as $item){
|
||||
$this->add($item, $categoryEnum, $group);
|
||||
}
|
||||
}
|
||||
$this->add($item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,16 +93,28 @@ final class CreativeInventory{
|
||||
* @phpstan-return array<int, Item>
|
||||
*/
|
||||
public function getAll() : array{
|
||||
return Utils::cloneObjectArray($this->creative);
|
||||
return array_map(fn(CreativeInventoryEntry $entry) => $entry->getItem(), $this->creative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CreativeInventoryEntry[]
|
||||
* @phpstan-return array<int, CreativeInventoryEntry>
|
||||
*/
|
||||
public function getAllEntries() : array{
|
||||
return $this->creative;
|
||||
}
|
||||
|
||||
public function getItem(int $index) : ?Item{
|
||||
return isset($this->creative[$index]) ? clone $this->creative[$index] : null;
|
||||
return $this->getEntry($index)?->getItem();
|
||||
}
|
||||
|
||||
public function getEntry(int $index) : ?CreativeInventoryEntry{
|
||||
return $this->creative[$index] ?? null;
|
||||
}
|
||||
|
||||
public function getItemIndex(Item $item) : int{
|
||||
foreach($this->creative as $i => $d){
|
||||
if($item->equals($d, true, false)){
|
||||
if($d->matchesItem($item)){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
@ -96,8 +126,8 @@ final class CreativeInventory{
|
||||
* Adds an item to the creative menu.
|
||||
* Note: Players who are already online when this is called will not see this change.
|
||||
*/
|
||||
public function add(Item $item) : void{
|
||||
$this->creative[] = clone $item;
|
||||
public function add(Item $item, CreativeCategory $category = CreativeCategory::ITEMS, ?CreativeGroup $group = null) : void{
|
||||
$this->creative[] = new CreativeInventoryEntry($item, $category, $group);
|
||||
$this->onContentChange();
|
||||
}
|
||||
|
||||
|
48
src/inventory/CreativeInventoryEntry.php
Normal file
48
src/inventory/CreativeInventoryEntry.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?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;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
final class CreativeInventoryEntry{
|
||||
private readonly Item $item;
|
||||
|
||||
public function __construct(
|
||||
Item $item,
|
||||
private readonly CreativeCategory $category,
|
||||
private readonly ?CreativeGroup $group = null
|
||||
){
|
||||
$this->item = clone $item;
|
||||
}
|
||||
|
||||
public function getItem() : Item{ return clone $this->item; }
|
||||
|
||||
public function getCategory() : CreativeCategory{ return $this->category; }
|
||||
|
||||
public function getGroup() : ?CreativeGroup{ return $this->group; }
|
||||
|
||||
public function matchesItem(Item $item) : bool{
|
||||
return $item->equals($this->item, checkDamage: true, checkCompound: false);
|
||||
}
|
||||
}
|
38
src/inventory/json/CreativeGroupData.php
Normal file
38
src/inventory/json/CreativeGroupData.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?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\json;
|
||||
|
||||
use pocketmine\crafting\json\ItemStackData;
|
||||
|
||||
final class CreativeGroupData{
|
||||
/** @required */
|
||||
public string $group_name;
|
||||
/** @required */
|
||||
public ?ItemStackData $group_icon;
|
||||
/**
|
||||
* @var \pocketmine\crafting\json\ItemStackData[]
|
||||
* @required
|
||||
*/
|
||||
public array $items;
|
||||
}
|
@ -232,7 +232,7 @@ class InventoryTransaction{
|
||||
|
||||
/**
|
||||
* @param SlotChangeAction[] $possibleActions
|
||||
* @phpstan-param list<SlotChangeAction> $possibleActions
|
||||
* @phpstan-param array<int, SlotChangeAction> $possibleActions
|
||||
*/
|
||||
protected function findResultItem(Item $needOrigin, array $possibleActions) : ?Item{
|
||||
assert(count($possibleActions) > 0);
|
||||
|
@ -101,8 +101,9 @@ abstract class WritableBookBase extends Item{
|
||||
* @return $this
|
||||
*/
|
||||
public function deletePage(int $pageId) : self{
|
||||
unset($this->pages[$pageId]);
|
||||
$this->pages = array_values($this->pages);
|
||||
$newPages = $this->pages;
|
||||
unset($newPages[$pageId]);
|
||||
$this->pages = array_values($newPages);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ use function array_merge;
|
||||
use function array_search;
|
||||
use function array_shift;
|
||||
use function array_unique;
|
||||
use function array_values;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
@ -103,7 +104,8 @@ final class ItemEnchantmentTagRegistry{
|
||||
|
||||
foreach(Utils::stringifyKeys($this->tagMap) as $key => $nestedTags){
|
||||
if(($nestedKey = array_search($tag, $nestedTags, true)) !== false){
|
||||
unset($this->tagMap[$key][$nestedKey]);
|
||||
unset($nestedTags[$nestedKey]);
|
||||
$this->tagMap[$key] = array_values($nestedTags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -115,7 +117,7 @@ final class ItemEnchantmentTagRegistry{
|
||||
*/
|
||||
public function removeNested(string $tag, array $nestedTags) : void{
|
||||
$this->assertNotInternalTag($tag);
|
||||
$this->tagMap[$tag] = array_diff($this->tagMap[$tag], $nestedTags);
|
||||
$this->tagMap[$tag] = array_values(array_diff($this->tagMap[$tag], $nestedTags));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,18 +25,22 @@ namespace pocketmine\item\enchantment;
|
||||
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\lang\Translatable;
|
||||
use function array_flip;
|
||||
use function array_fill_keys;
|
||||
use function floor;
|
||||
|
||||
class ProtectionEnchantment extends Enchantment{
|
||||
protected float $typeModifier;
|
||||
/** @var int[]|null */
|
||||
/**
|
||||
* @var true[]|null
|
||||
* @phpstan-var array<int, true>
|
||||
*/
|
||||
protected ?array $applicableDamageTypes = null;
|
||||
|
||||
/**
|
||||
* ProtectionEnchantment constructor.
|
||||
*
|
||||
* @phpstan-param null|(\Closure(int $level) : int) $minEnchantingPower
|
||||
* @phpstan-param list<int>|null $applicableDamageTypes
|
||||
*
|
||||
* @param int $primaryItemFlags @deprecated
|
||||
* @param int $secondaryItemFlags @deprecated
|
||||
@ -48,7 +52,7 @@ class ProtectionEnchantment extends Enchantment{
|
||||
|
||||
$this->typeModifier = $typeModifier;
|
||||
if($applicableDamageTypes !== null){
|
||||
$this->applicableDamageTypes = array_flip($applicableDamageTypes);
|
||||
$this->applicableDamageTypes = array_fill_keys($applicableDamageTypes, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,6 +897,18 @@ final class KnownTranslationFactory{
|
||||
return new Translatable(KnownTranslationKeys::ENCHANTMENT_FROSTWALKER, []);
|
||||
}
|
||||
|
||||
public static function enchantment_heavy_weapon_breach() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ENCHANTMENT_HEAVY_WEAPON_BREACH, []);
|
||||
}
|
||||
|
||||
public static function enchantment_heavy_weapon_density() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ENCHANTMENT_HEAVY_WEAPON_DENSITY, []);
|
||||
}
|
||||
|
||||
public static function enchantment_heavy_weapon_windburst() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ENCHANTMENT_HEAVY_WEAPON_WINDBURST, []);
|
||||
}
|
||||
|
||||
public static function enchantment_knockback() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ENCHANTMENT_KNOCKBACK, []);
|
||||
}
|
||||
@ -1108,6 +1120,318 @@ final class KnownTranslationFactory{
|
||||
return new Translatable(KnownTranslationKeys::ITEM_RECORD_WARD_DESC, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_anvil() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_ANVIL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_arrow() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_ARROW, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_axe() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_AXE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_banner() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BANNER, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_banner_pattern() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BANNER_PATTERN, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_bed() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BED, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_boat() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BOAT, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_boots() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BOOTS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_bundles() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BUNDLES, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_buttons() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_BUTTONS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_candles() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CANDLES, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_chalkboard() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CHALKBOARD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_chest() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CHEST, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_chestboat() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CHESTBOAT, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_chestplate() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CHESTPLATE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_compounds() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_COMPOUNDS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_concrete() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CONCRETE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_concretePowder() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CONCRETEPOWDER, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_cookedFood() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_COOKEDFOOD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_coral() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CORAL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_coral_decorations() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CORAL_DECORATIONS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_crop() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_CROP, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_door() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_DOOR, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_dye() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_DYE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_enchantedBook() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_ENCHANTEDBOOK, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_fence() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_FENCE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_fenceGate() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_FENCEGATE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_firework() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_FIREWORK, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_fireworkStars() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_FIREWORKSTARS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_flower() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_FLOWER, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_glass() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_GLASS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_glassPane() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_GLASSPANE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_glazedTerracotta() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_GLAZEDTERRACOTTA, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_goatHorn() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_GOATHORN, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_grass() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_GRASS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_helmet() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_HELMET, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_hoe() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_HOE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_horseArmor() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_HORSEARMOR, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_leaves() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_LEAVES, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_leggings() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_LEGGINGS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_lingeringPotion() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_LINGERINGPOTION, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_log() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_LOG, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_minecart() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_MINECART, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_miscFood() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_MISCFOOD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_mobEgg() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_MOBEGG, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_monsterStoneEgg() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_MONSTERSTONEEGG, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_mushroom() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_MUSHROOM, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_netherWartBlock() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_NETHERWARTBLOCK, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_ominousBottle() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_OMINOUSBOTTLE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_ore() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_ORE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_permission() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_PERMISSION, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_pickaxe() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_PICKAXE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_planks() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_PLANKS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_potion() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_POTION, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_pressurePlate() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_PRESSUREPLATE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_products() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_PRODUCTS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_rail() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_RAIL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_rawFood() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_RAWFOOD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_record() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_RECORD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_sandstone() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SANDSTONE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_sapling() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SAPLING, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_seed() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SEED, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_shovel() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SHOVEL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_shulkerBox() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SHULKERBOX, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_sign() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SIGN, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_skull() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SKULL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_slab() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SLAB, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_splashPotion() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SPLASHPOTION, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_stainedClay() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_STAINEDCLAY, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_stairs() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_STAIRS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_stone() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_STONE, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_stoneBrick() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_STONEBRICK, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_sword() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_SWORD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_trapdoor() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_TRAPDOOR, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_walls() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_WALLS, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_wood() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_WOOD, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_wool() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_WOOL, []);
|
||||
}
|
||||
|
||||
public static function itemGroup_name_woolCarpet() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::ITEMGROUP_NAME_WOOLCARPET, []);
|
||||
}
|
||||
|
||||
public static function kick_admin() : Translatable{
|
||||
return new Translatable(KnownTranslationKeys::KICK_ADMIN, []);
|
||||
}
|
||||
|
@ -194,6 +194,9 @@ final class KnownTranslationKeys{
|
||||
public const ENCHANTMENT_FIRE = "enchantment.fire";
|
||||
public const ENCHANTMENT_FISHINGSPEED = "enchantment.fishingSpeed";
|
||||
public const ENCHANTMENT_FROSTWALKER = "enchantment.frostwalker";
|
||||
public const ENCHANTMENT_HEAVY_WEAPON_BREACH = "enchantment.heavy_weapon.breach";
|
||||
public const ENCHANTMENT_HEAVY_WEAPON_DENSITY = "enchantment.heavy_weapon.density";
|
||||
public const ENCHANTMENT_HEAVY_WEAPON_WINDBURST = "enchantment.heavy_weapon.windburst";
|
||||
public const ENCHANTMENT_KNOCKBACK = "enchantment.knockback";
|
||||
public const ENCHANTMENT_LOOTBONUS = "enchantment.lootBonus";
|
||||
public const ENCHANTMENT_LOOTBONUSDIGGER = "enchantment.lootBonusDigger";
|
||||
@ -245,6 +248,84 @@ final class KnownTranslationKeys{
|
||||
public const ITEM_RECORD_STRAD_DESC = "item.record_strad.desc";
|
||||
public const ITEM_RECORD_WAIT_DESC = "item.record_wait.desc";
|
||||
public const ITEM_RECORD_WARD_DESC = "item.record_ward.desc";
|
||||
public const ITEMGROUP_NAME_ANVIL = "itemGroup.name.anvil";
|
||||
public const ITEMGROUP_NAME_ARROW = "itemGroup.name.arrow";
|
||||
public const ITEMGROUP_NAME_AXE = "itemGroup.name.axe";
|
||||
public const ITEMGROUP_NAME_BANNER = "itemGroup.name.banner";
|
||||
public const ITEMGROUP_NAME_BANNER_PATTERN = "itemGroup.name.banner_pattern";
|
||||
public const ITEMGROUP_NAME_BED = "itemGroup.name.bed";
|
||||
public const ITEMGROUP_NAME_BOAT = "itemGroup.name.boat";
|
||||
public const ITEMGROUP_NAME_BOOTS = "itemGroup.name.boots";
|
||||
public const ITEMGROUP_NAME_BUNDLES = "itemGroup.name.bundles";
|
||||
public const ITEMGROUP_NAME_BUTTONS = "itemGroup.name.buttons";
|
||||
public const ITEMGROUP_NAME_CANDLES = "itemGroup.name.candles";
|
||||
public const ITEMGROUP_NAME_CHALKBOARD = "itemGroup.name.chalkboard";
|
||||
public const ITEMGROUP_NAME_CHEST = "itemGroup.name.chest";
|
||||
public const ITEMGROUP_NAME_CHESTBOAT = "itemGroup.name.chestboat";
|
||||
public const ITEMGROUP_NAME_CHESTPLATE = "itemGroup.name.chestplate";
|
||||
public const ITEMGROUP_NAME_COMPOUNDS = "itemGroup.name.compounds";
|
||||
public const ITEMGROUP_NAME_CONCRETE = "itemGroup.name.concrete";
|
||||
public const ITEMGROUP_NAME_CONCRETEPOWDER = "itemGroup.name.concretePowder";
|
||||
public const ITEMGROUP_NAME_COOKEDFOOD = "itemGroup.name.cookedFood";
|
||||
public const ITEMGROUP_NAME_CORAL = "itemGroup.name.coral";
|
||||
public const ITEMGROUP_NAME_CORAL_DECORATIONS = "itemGroup.name.coral_decorations";
|
||||
public const ITEMGROUP_NAME_CROP = "itemGroup.name.crop";
|
||||
public const ITEMGROUP_NAME_DOOR = "itemGroup.name.door";
|
||||
public const ITEMGROUP_NAME_DYE = "itemGroup.name.dye";
|
||||
public const ITEMGROUP_NAME_ENCHANTEDBOOK = "itemGroup.name.enchantedBook";
|
||||
public const ITEMGROUP_NAME_FENCE = "itemGroup.name.fence";
|
||||
public const ITEMGROUP_NAME_FENCEGATE = "itemGroup.name.fenceGate";
|
||||
public const ITEMGROUP_NAME_FIREWORK = "itemGroup.name.firework";
|
||||
public const ITEMGROUP_NAME_FIREWORKSTARS = "itemGroup.name.fireworkStars";
|
||||
public const ITEMGROUP_NAME_FLOWER = "itemGroup.name.flower";
|
||||
public const ITEMGROUP_NAME_GLASS = "itemGroup.name.glass";
|
||||
public const ITEMGROUP_NAME_GLASSPANE = "itemGroup.name.glassPane";
|
||||
public const ITEMGROUP_NAME_GLAZEDTERRACOTTA = "itemGroup.name.glazedTerracotta";
|
||||
public const ITEMGROUP_NAME_GOATHORN = "itemGroup.name.goatHorn";
|
||||
public const ITEMGROUP_NAME_GRASS = "itemGroup.name.grass";
|
||||
public const ITEMGROUP_NAME_HELMET = "itemGroup.name.helmet";
|
||||
public const ITEMGROUP_NAME_HOE = "itemGroup.name.hoe";
|
||||
public const ITEMGROUP_NAME_HORSEARMOR = "itemGroup.name.horseArmor";
|
||||
public const ITEMGROUP_NAME_LEAVES = "itemGroup.name.leaves";
|
||||
public const ITEMGROUP_NAME_LEGGINGS = "itemGroup.name.leggings";
|
||||
public const ITEMGROUP_NAME_LINGERINGPOTION = "itemGroup.name.lingeringPotion";
|
||||
public const ITEMGROUP_NAME_LOG = "itemGroup.name.log";
|
||||
public const ITEMGROUP_NAME_MINECART = "itemGroup.name.minecart";
|
||||
public const ITEMGROUP_NAME_MISCFOOD = "itemGroup.name.miscFood";
|
||||
public const ITEMGROUP_NAME_MOBEGG = "itemGroup.name.mobEgg";
|
||||
public const ITEMGROUP_NAME_MONSTERSTONEEGG = "itemGroup.name.monsterStoneEgg";
|
||||
public const ITEMGROUP_NAME_MUSHROOM = "itemGroup.name.mushroom";
|
||||
public const ITEMGROUP_NAME_NETHERWARTBLOCK = "itemGroup.name.netherWartBlock";
|
||||
public const ITEMGROUP_NAME_OMINOUSBOTTLE = "itemGroup.name.ominousBottle";
|
||||
public const ITEMGROUP_NAME_ORE = "itemGroup.name.ore";
|
||||
public const ITEMGROUP_NAME_PERMISSION = "itemGroup.name.permission";
|
||||
public const ITEMGROUP_NAME_PICKAXE = "itemGroup.name.pickaxe";
|
||||
public const ITEMGROUP_NAME_PLANKS = "itemGroup.name.planks";
|
||||
public const ITEMGROUP_NAME_POTION = "itemGroup.name.potion";
|
||||
public const ITEMGROUP_NAME_PRESSUREPLATE = "itemGroup.name.pressurePlate";
|
||||
public const ITEMGROUP_NAME_PRODUCTS = "itemGroup.name.products";
|
||||
public const ITEMGROUP_NAME_RAIL = "itemGroup.name.rail";
|
||||
public const ITEMGROUP_NAME_RAWFOOD = "itemGroup.name.rawFood";
|
||||
public const ITEMGROUP_NAME_RECORD = "itemGroup.name.record";
|
||||
public const ITEMGROUP_NAME_SANDSTONE = "itemGroup.name.sandstone";
|
||||
public const ITEMGROUP_NAME_SAPLING = "itemGroup.name.sapling";
|
||||
public const ITEMGROUP_NAME_SEED = "itemGroup.name.seed";
|
||||
public const ITEMGROUP_NAME_SHOVEL = "itemGroup.name.shovel";
|
||||
public const ITEMGROUP_NAME_SHULKERBOX = "itemGroup.name.shulkerBox";
|
||||
public const ITEMGROUP_NAME_SIGN = "itemGroup.name.sign";
|
||||
public const ITEMGROUP_NAME_SKULL = "itemGroup.name.skull";
|
||||
public const ITEMGROUP_NAME_SLAB = "itemGroup.name.slab";
|
||||
public const ITEMGROUP_NAME_SPLASHPOTION = "itemGroup.name.splashPotion";
|
||||
public const ITEMGROUP_NAME_STAINEDCLAY = "itemGroup.name.stainedClay";
|
||||
public const ITEMGROUP_NAME_STAIRS = "itemGroup.name.stairs";
|
||||
public const ITEMGROUP_NAME_STONE = "itemGroup.name.stone";
|
||||
public const ITEMGROUP_NAME_STONEBRICK = "itemGroup.name.stoneBrick";
|
||||
public const ITEMGROUP_NAME_SWORD = "itemGroup.name.sword";
|
||||
public const ITEMGROUP_NAME_TRAPDOOR = "itemGroup.name.trapdoor";
|
||||
public const ITEMGROUP_NAME_WALLS = "itemGroup.name.walls";
|
||||
public const ITEMGROUP_NAME_WOOD = "itemGroup.name.wood";
|
||||
public const ITEMGROUP_NAME_WOOL = "itemGroup.name.wool";
|
||||
public const ITEMGROUP_NAME_WOOLCARPET = "itemGroup.name.woolCarpet";
|
||||
public const KICK_ADMIN = "kick.admin";
|
||||
public const KICK_ADMIN_REASON = "kick.admin.reason";
|
||||
public const KICK_REASON_CHEAT = "kick.reason.cheat";
|
||||
|
@ -690,7 +690,7 @@ class InventoryManager{
|
||||
}
|
||||
|
||||
public function syncCreative() : void{
|
||||
$this->session->sendDataPacket(CreativeInventoryCache::getInstance()->getCache($this->player->getCreativeInventory()));
|
||||
$this->session->sendDataPacket(CreativeInventoryCache::getInstance()->buildPacket($this->player->getCreativeInventory(), $this->session));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,9 +115,9 @@ use pocketmine\utils\ObjectSet;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\world\format\io\GlobalItemDataHandlers;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\World;
|
||||
use pocketmine\YmlServerProperties;
|
||||
use function array_map;
|
||||
use function array_values;
|
||||
use function base64_encode;
|
||||
use function bin2hex;
|
||||
use function count;
|
||||
@ -163,7 +163,10 @@ class NetworkSession{
|
||||
|
||||
private ?EncryptionContext $cipher = null;
|
||||
|
||||
/** @var string[] */
|
||||
/**
|
||||
* @var string[]
|
||||
* @phpstan-var list<string>
|
||||
*/
|
||||
private array $sendBuffer = [];
|
||||
/**
|
||||
* @var PromiseResolver[]
|
||||
@ -543,6 +546,7 @@ class NetworkSession{
|
||||
* @phpstan-return Promise<true>
|
||||
*/
|
||||
public function sendDataPacketWithReceipt(ClientboundPacket $packet, bool $immediate = false) : Promise{
|
||||
/** @phpstan-var PromiseResolver<true> $resolver */
|
||||
$resolver = new PromiseResolver();
|
||||
|
||||
if(!$this->sendDataPacketInternal($packet, $immediate, $resolver)){
|
||||
@ -1054,8 +1058,7 @@ class NetworkSession{
|
||||
];
|
||||
|
||||
$layers = [
|
||||
//TODO: dynamic flying speed! FINALLY!!!!!!!!!!!!!!!!!
|
||||
new AbilitiesLayer(AbilitiesLayer::LAYER_BASE, $boolAbilities, 0.05, 0.1),
|
||||
new AbilitiesLayer(AbilitiesLayer::LAYER_BASE, $boolAbilities, $for->getFlightSpeedMultiplier(), 1, 0.1),
|
||||
];
|
||||
if(!$for->hasBlockCollision()){
|
||||
//TODO: HACK! In 1.19.80, the client starts falling in our faux spectator mode when it clips into a
|
||||
@ -1065,7 +1068,7 @@ class NetworkSession{
|
||||
|
||||
$layers[] = new AbilitiesLayer(AbilitiesLayer::LAYER_SPECTATOR, [
|
||||
AbilitiesLayer::ABILITY_FLYING => true,
|
||||
], null, null);
|
||||
], null, null, null);
|
||||
}
|
||||
|
||||
$this->sendDataPacket(UpdateAbilitiesPacket::create(new AbilitiesData(
|
||||
@ -1105,7 +1108,7 @@ class NetworkSession{
|
||||
//work around a client bug which makes the original name not show when aliases are used
|
||||
$aliases[] = $lname;
|
||||
}
|
||||
$aliasObj = new CommandEnum(ucfirst($command->getLabel()) . "Aliases", array_values($aliases));
|
||||
$aliasObj = new CommandEnum(ucfirst($command->getLabel()) . "Aliases", $aliases);
|
||||
}
|
||||
|
||||
$description = $command->getDescription();
|
||||
@ -1178,6 +1181,19 @@ class NetworkSession{
|
||||
$this->sendDataPacket(ClientboundCloseFormPacket::create());
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param \Closure() : void $onCompletion
|
||||
*/
|
||||
private function sendChunkPacket(string $chunkPacket, \Closure $onCompletion, World $world) : void{
|
||||
$world->timings->syncChunkSend->startTiming();
|
||||
try{
|
||||
$this->queueCompressed($chunkPacket);
|
||||
$onCompletion();
|
||||
}finally{
|
||||
$world->timings->syncChunkSend->stopTiming();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously.
|
||||
* @param \Closure $onCompletion To be called when chunk sending has completed.
|
||||
@ -1185,8 +1201,12 @@ class NetworkSession{
|
||||
*/
|
||||
public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{
|
||||
$world = $this->player->getLocation()->getWorld();
|
||||
ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve(
|
||||
|
||||
$promiseOrPacket = ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ);
|
||||
if(is_string($promiseOrPacket)){
|
||||
$this->sendChunkPacket($promiseOrPacket, $onCompletion, $world);
|
||||
return;
|
||||
}
|
||||
$promiseOrPacket->onResolve(
|
||||
//this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet
|
||||
function(CompressBatchPromise $promise) use ($world, $onCompletion, $chunkX, $chunkZ) : void{
|
||||
if(!$this->isConnected()){
|
||||
@ -1204,13 +1224,7 @@ class NetworkSession{
|
||||
//to NEEDED if they want to be resent.
|
||||
return;
|
||||
}
|
||||
$world->timings->syncChunkSend->startTiming();
|
||||
try{
|
||||
$this->queueCompressed($promise);
|
||||
$onCompletion();
|
||||
}finally{
|
||||
$world->timings->syncChunkSend->stopTiming();
|
||||
}
|
||||
$this->sendChunkPacket($promise->getResult(), $onCompletion, $world);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user