Compare commits

..

63 Commits
4.4.1 ... 4.6.2

Author SHA1 Message Date
9abbb85a93 Release 4.6.2 2022-08-06 15:35:47 +01:00
554182b2cb Update composer dependencies 2022-08-06 15:27:11 +01:00
d669a6f0c7 ReversePriorityQueue: add ReturnTypeWillChange attribute
it's doubtful any plugin dev is extending this, but nonetheless, we can't change it in a patch.
2022-07-27 03:51:06 +01:00
5d9f783037 InGamePacketHandler: do not update player rotation if it didn't change
setRotation() does an alarmingly large amount of work...
2022-07-24 21:07:35 +01:00
01ca14c314 InGamePacketHandler: avoid processing movement if position is unchanged since last tick 2022-07-24 21:00:12 +01:00
608c6ed6db Improved suboptimal code in Player::handleMovement() 2022-07-24 20:51:28 +01:00
c26631d06d InGamePacketHandler: avoid useless object allocations when forceMoveSync=false (99.9% of the time) 2022-07-24 20:44:27 +01:00
b75bc61a64 InGamePacketHandler: don't bother checking for flag changes if the flag fields are identical
we don't need to check this on a bit by bit level if the integers are the same.

this saves 2-3 microseconds per packet on my machine, which doesn't sound like much, but it adds up when there are lots of players.
2022-07-24 20:35:49 +01:00
3724479be3 InGamePacketHandler: improve performance of input flag resolving 2022-07-24 20:33:35 +01:00
eb916fe43d Use a falling block entity to improve client side performance of FloatingTextParticle (#4714)
Performance tests show that this has a considerable client-side performance advantage over using players. In my local tests, using 1000 floating texts in a 10x10x10 area, I observed an FPS increase from 1.5 to 8.0.
2022-07-24 18:22:21 +01:00
5e3b3a0700 Fix assert spam on debug clients 2022-07-24 17:51:02 +01:00
e10a624444 4.6.2 is next 2022-07-22 19:35:10 +01:00
b20e04539d Release 4.6.1 2022-07-22 19:34:57 +01:00
4852f8029a AsyncTask: update documentation 2022-07-21 23:26:46 +01:00
c4f85e526b Bump shivammathur/setup-php from 2.20.0 to 2.21.0 (#5181)
Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.20.0 to 2.21.0.
- [Release notes](https://github.com/shivammathur/setup-php/releases)
- [Commits](https://github.com/shivammathur/setup-php/compare/2.20.0...2.21.0)

---
updated-dependencies:
- dependency-name: shivammathur/setup-php
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-20 15:19:21 +01:00
6cee428287 Bump docker/build-push-action from 3.0.0 to 3.1.0 (#5182)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-20 15:18:38 +01:00
bcba064d69 Bump build/php from 1110349 to f292501 (#5180)
Bumps [build/php](https://github.com/pmmp/php-build-scripts) from `1110349` to `f292501`.
- [Release notes](https://github.com/pmmp/php-build-scripts/releases)
- [Commits](11103498ca...f292501a70)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-20 15:16:34 +01:00
86647683bc fix CS again 2022-07-19 20:35:34 +01:00
64f0e58e60 Merge branch 'stable' of github.com:pmmp/PocketMine-MP into stable 2022-07-19 20:17:15 +01:00
62f21516d1 build/generate-registry-annotations.php: allow processing a single file
this is useful for automatically invoking the script via a PhpStorm file watcher.
2022-07-19 20:17:07 +01:00
c553f7cf06 build/generate-registry-annotations.php: write to stderr on error 2022-07-19 20:15:44 +01:00
fec89b7803 Lava burns entities for only 8 seconds in Bedrock (#5173) 2022-07-17 20:50:15 +01:00
2b61c025c2 Workaround items in blockentity NBT not being processed correctly in 1.19.10
closes #5154

this hack sends only the bare essential data to create the tiles in LevelChunkPacket,
and then separately sending the full tile data using BlockActorDataPacket afterwards.

This is necessary because the client doesn't handle items correctly in NBT when chunks are sent without using the SubChunkRequest system.
In 4.6 this is observed with incorrect items shown in item frames; in 5.0 it's seen with items simply not showing up at all (difference due to modernization of the serialization format in 5.0).
2022-07-14 21:54:01 +01:00
c7133bc2e6 InGamePacketHandler: don't kick the player out of inventory windows on actor events
this is sent when the player crafts something using an anvil.
2022-07-14 20:36:11 +01:00
baf75089f5 Entity: cancel fire damage for fireproof entities 2022-07-14 19:53:25 +01:00
Ali
705df7d508 EffectManager: remove redundant check (#5153) 2022-07-14 17:56:18 +01:00
75d7adfb2d WitherEffect: fixed incorrect damage interval 2022-07-14 16:05:35 +01:00
9d535e2917 4.6.1 is next 2022-07-13 01:28:42 +01:00
3ccd288afd Release 4.6.0 2022-07-13 01:28:37 +01:00
06655bee78 Updated to 1.19.10 2022-07-13 00:59:49 +01:00
0ad2985247 Update documentation for Item::__construct() 2022-07-06 23:54:29 +01:00
269b6ed16a FallableTrait: fixed logic for block replacement
closes #5126

I don't know why it wasn't done this way to begin with. FallingBlock always used canBeReplaced()...
2022-07-06 16:16:49 +01:00
f031c3c602 Updated NBT dependency 2022-07-06 15:19:19 +01:00
f3e09dd7d5 Bump shivammathur/setup-php from 2.19.1 to 2.20.0 (#5135)
Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.19.1 to 2.20.0.
- [Release notes](https://github.com/shivammathur/setup-php/releases)
- [Commits](https://github.com/shivammathur/setup-php/compare/2.19.1...2.20.0)

---
updated-dependencies:
- dependency-name: shivammathur/setup-php
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-06 13:28:46 +01:00
68e704bf97 Bump shivammathur/setup-php from 2.19.0 to 2.19.1 (#5098)
Bumps [shivammathur/setup-php](https://github.com/shivammathur/setup-php) from 2.19.0 to 2.19.1.
- [Release notes](https://github.com/shivammathur/setup-php/releases)
- [Commits](https://github.com/shivammathur/setup-php/compare/2.19.0...2.19.1)

---
updated-dependencies:
- dependency-name: shivammathur/setup-php
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 15:15:17 +01:00
9898577135 Bump phpstan/phpstan from 1.7.15 to 1.8.0 (#5120)
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.7.15 to 1.8.0.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Changelog](https://github.com/phpstan/phpstan/blob/1.8.x/CHANGELOG.md)
- [Commits](https://github.com/phpstan/phpstan/compare/1.7.15...1.8.0)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-30 16:09:03 +01:00
784d602600 Fixed ItemBreakParticle using untranslated internal ID/meta for network data
this caused it to display particles for incorrect items. It may also have been possibly responsible for client crashes.
2022-06-29 14:01:39 +01:00
15c99cfe77 4.5.3 is next 2022-06-29 02:18:50 +01:00
d5fa0a2fc5 Release 4.5.2 2022-06-29 02:18:50 +01:00
0da9260994 Updated composer dependencies 2022-06-29 02:13:32 +01:00
df2d1fd4f9 of course there were two bugs on one line ... 2022-06-24 01:40:26 +01:00
9f65fb5f90 Fixed top-side skulls with no-drop flag set being treated as unknown blocks 2022-06-24 01:31:11 +01:00
caa4b78a3f Update composer dependencies 2022-06-21 20:21:02 +01:00
14352a05bc reword support bot message 2022-06-11 15:54:44 +01:00
bb5b52d998 Player: fix terrain getting redrawn when moving in noclip mode 2022-06-09 13:48:29 +01:00
5e22b70b6d this is a joke ... 2022-06-08 14:56:25 +01:00
02513818a9 4.5.2 is next 2022-06-08 02:50:34 +01:00
d641812c52 Release 4.5.1 2022-06-08 02:50:33 +01:00
a851496293 Updated BedrockProtocol 2022-06-08 02:46:01 +01:00
01a8bce2dd Fix whitespace error in support.yml workflow 2022-06-07 19:54:51 +01:00
becbd562d6 FormattedCommandAlias: fixed incorrect arguments array being passed to the target 2022-06-07 19:47:45 +01:00
82edb20e0c 4.5.1 is next 2022-06-07 17:57:39 +01:00
64a8c462f9 Release 4.5.0 2022-06-07 17:57:39 +01:00
4ec97d0f7a InGamePacketHandler: added missing break
I'm getting sloppy ...
2022-06-07 17:52:59 +01:00
016a80bb70 1.19.0 changes 2022-06-07 17:47:13 +01:00
ce66a400a7 Updated composer dependencies 2022-06-07 17:44:06 +01:00
50776875bb 4.4.3 is next 2022-06-07 15:54:55 +01:00
bcb0e2ff1f Release 4.4.2 2022-06-07 15:54:55 +01:00
1584768c80 PaintingMotive: fixed botched painting fix from 0ea3861d43
I knew I should have used a singleton for this ...
2022-06-07 15:48:20 +01:00
5fd685e07d TypeConverter: fix crash on arbitrary out-of-bounds item IDs
I don't know why I didn't consider this fix necessary when the item meta bug was originally discovered.
2022-06-06 19:29:44 +01:00
6ecfbd1bde FishingRod: make class less useless 2022-06-05 20:20:16 +01:00
b661097c51 changelog: fix mistake
[ci skip]
2022-06-05 17:59:36 +01:00
0771295899 4.4.2 is next 2022-06-05 16:15:38 +01:00
36 changed files with 462 additions and 354 deletions

View File

@ -46,7 +46,7 @@ jobs:
run: echo ::set-output name=NAME::$(echo "${GITHUB_REPOSITORY,,}")
- name: Build image for tag
uses: docker/build-push-action@v3.0.0
uses: docker/build-push-action@v3.1.0
with:
push: true
context: ./pocketmine-mp
@ -59,7 +59,7 @@ jobs:
- name: Build image for major tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v3.0.0
uses: docker/build-push-action@v3.1.0
with:
push: true
context: ./pocketmine-mp
@ -72,7 +72,7 @@ jobs:
- name: Build image for minor tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v3.0.0
uses: docker/build-push-action@v3.1.0
with:
push: true
context: ./pocketmine-mp
@ -85,7 +85,7 @@ jobs:
- name: Build image for latest tag
if: steps.channel.outputs.CHANNEL == 'stable'
uses: docker/build-push-action@v3.0.0
uses: docker/build-push-action@v3.1.0
with:
push: true
context: ./pocketmine-mp

View File

@ -18,7 +18,7 @@ jobs:
submodules: true
- name: Setup PHP
uses: shivammathur/setup-php@2.19.0
uses: shivammathur/setup-php@2.21.0
with:
php-version: 8.0

View File

@ -195,7 +195,7 @@ jobs:
- uses: actions/checkout@v3
- name: Setup PHP and tools
uses: shivammathur/setup-php@2.19.0
uses: shivammathur/setup-php@2.21.0
with:
php-version: 8.0
tools: php-cs-fixer:3.2

View File

@ -16,9 +16,10 @@ jobs:
Hi, we only accept **bug reports** on this issue tracker, but this issue looks like a support request.
Instead of creating a bug report, try the following:
Instead of creating an issue, try the following:
- Check our [Documentation](https://doc.pmmp.io) to see if you can find answers there
- Ask the community on our [Discord server](https://discord.gg/bmSAZBG) or our [Forums](https://forums.pmmp.io)

View File

@ -29,7 +29,9 @@ use function count;
use function dirname;
use function file_get_contents;
use function file_put_contents;
use function fwrite;
use function implode;
use function is_dir;
use function ksort;
use function mb_strtoupper;
use function preg_match;
@ -39,7 +41,8 @@ use function substr;
use const SORT_STRING;
if(count($argv) !== 2){
die("Provide a path to process");
fwrite(STDERR, "Provide a path to process\n");
exit(1);
}
/**
@ -80,30 +83,24 @@ function generateMethodAnnotations(string $namespaceName, array $members) : stri
return implode("\n", $lines);
}
require dirname(__DIR__) . '/vendor/autoload.php';
/** @var string $file */
foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $file){
if(substr($file, -4) !== ".php"){
continue;
}
function processFile(string $file) : void{
$contents = file_get_contents($file);
if($contents === false){
throw new \RuntimeException("Failed to get contents of $file");
}
if(preg_match("/(*ANYCRLF)^namespace (.+);$/m", $contents, $matches) !== 1 || preg_match('/(*ANYCRLF)^((final|abstract)\s+)?class /m', $contents) !== 1){
continue;
return;
}
$shortClassName = basename($file, ".php");
$className = $matches[1] . "\\" . $shortClassName;
if(!class_exists($className)){
continue;
return;
}
$reflect = new \ReflectionClass($className);
$docComment = $reflect->getDocComment();
if($docComment === false || preg_match("/(*ANYCRLF)^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1){
continue;
return;
}
echo "Found registry in $file\n";
@ -117,3 +114,18 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1],
echo "No changes made to file $file\n";
}
}
require dirname(__DIR__) . '/vendor/autoload.php';
if(is_dir($argv[1])){
/** @var string $file */
foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $file){
if(substr($file, -4) !== ".php"){
continue;
}
processFile($file);
}
}else{
processFile($argv[1]);
}

View File

@ -84,6 +84,14 @@ Released 5th June 2022.
## Fixes
- Fixed graylisted plugins preventing the server from starting.
- Fixed `composer make-server` command.
- Fixed `composer make-devtools` command.
- Fixed the `Maximum memory (manager)` units being incorrectly displayed in `/status`.
- Fixed `Player->removeCurrentWindow()` breaking inventory windows.
# 4.4.2
Released 7th June 2022.
## Fixes
- Fixed a crash when arbitrary item IDs appeared in network items in some cases.
- Fixed saved paintings being deleted when loaded from disk (regression from 4.3.4).
- Fixed max stack size of fishing rods.

28
changelogs/4.5.md Normal file
View File

@ -0,0 +1,28 @@
**For Minecraft: Bedrock Edition 1.19.0**
### Note about API versions
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
Plugin developers should **only** update their required API to this version if you need the changes in this build.
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
# 4.5.0
Released 7th June 2022.
## General
- Added support for Minecraft: Bedrock Edition 1.19.0.
- Removed support for older versions.
# 4.5.1
Released 8th June 2022.
## Fixes
- Fixed commands defined in `pocketmine.yml` `aliases` not passing the correct arguments.
- Updated BedrockProtocol to fix command argument types displayed on client-side command suggestions.
# 4.5.2
Released 29th June 2022.
## Fixes
- Fixed terrain getting redrawn when flying in spectator mode (or when using `Player->setHasBlockCollision(false)`).
- Fixed skulls with the `noDrops` flag set being treated as unknown blocks.

42
changelogs/4.6.md Normal file
View File

@ -0,0 +1,42 @@
**For Minecraft: Bedrock Edition 1.19.10**
### Note about API versions
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
Plugin developers should **only** update their required API to this version if you need the changes in this build.
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
# 4.6.0
Released 13th July 2022.
## General
- Added support for Minecraft: Bedrock Edition 1.19.10.
- Removed support for older versions.
# 4.6.1
Released 22nd July 2022.
## Tools
- `build/generate-registry-annotations.php` now supports processing single files (useful for PhpStorm file watchers).
## API
- Updated documentation for `AsyncTask`.
## Fixes
- Fixed incorrect items being displayed in item frames.
- Fixed books not showing in lecterns.
- Fixed incorrect damage interval of Wither status effect.
- Fixed incorrect fire ticks when being set on fire by lava (8 seconds in Bedrock instead of 15).
- `Entity->attack()` now cancels damage from `FIRE` and `FIRE_TICK` damage causes if the entity is fireproof.
- Fixed inventory windows getting force-closed when the client attempts to use an enchanting table or anvil.
# 4.6.2
Released 6th August 2022.
## Core
- Improved server-side performance of `PlayerAuthInputPacket` handler.
- Improved client-side performance of `FloatingTextParticle` by using an invisible falling block entity. This offered a roughly 5x performance improvement over using tiny invisible players in local testing.
## Fixes
- Fixed assert failures and debug spam on debug Minecraft clients related to abilities in `AddPlayerPacket`.
- Fixed crash in `ReversePriorityQueue` on PHP 8.1 by adding `#[ReturnTypeWillChange]` attribute.

View File

@ -34,8 +34,8 @@
"adhocore/json-comment": "^1.1",
"fgrosse/phpasn1": "^2.3",
"netresearch/jsonmapper": "^4.0",
"pocketmine/bedrock-data": "~1.7.0+bedrock-1.18.30",
"pocketmine/bedrock-protocol": "~9.0.0+bedrock-1.18.30",
"pocketmine/bedrock-data": "~1.9.0+bedrock-1.19.10",
"pocketmine/bedrock-protocol": "~11.0.0+bedrock-1.19.10",
"pocketmine/binaryutils": "^0.2.1",
"pocketmine/callback-validator": "^1.0.2",
"pocketmine/classloader": "^0.2.0",
@ -53,7 +53,7 @@
"webmozart/path-util": "^2.3"
},
"require-dev": {
"phpstan/phpstan": "1.7.8",
"phpstan/phpstan": "1.8.2",
"phpstan/phpstan-phpunit": "^1.1.0",
"phpstan/phpstan-strict-rules": "^1.2.0",
"phpunit/phpunit": "^9.2"

230
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1e967ff64cee3cae84242cc3e5a51752",
"content-hash": "f9d81230e16fff707deb5cbe7ff37376",
"packages": [
{
"name": "adhocore/json-comment",
@ -63,26 +63,26 @@
},
{
"name": "brick/math",
"version": "0.9.3",
"version": "0.10.1",
"source": {
"type": "git",
"url": "https://github.com/brick/math.git",
"reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae"
"reference": "de846578401f4e58f911b3afeb62ced56365ed87"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae",
"reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae",
"url": "https://api.github.com/repos/brick/math/zipball/de846578401f4e58f911b3afeb62ced56365ed87",
"reference": "de846578401f4e58f911b3afeb62ced56365ed87",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.1 || ^8.0"
"php": "^7.4 || ^8.0"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
"vimeo/psalm": "4.9.2"
"phpunit/phpunit": "^9.0",
"vimeo/psalm": "4.25.0"
},
"type": "library",
"autoload": {
@ -107,19 +107,15 @@
],
"support": {
"issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.9.3"
"source": "https://github.com/brick/math/tree/0.10.1"
},
"funding": [
{
"url": "https://github.com/BenMorel",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/brick/math",
"type": "tidelift"
}
],
"time": "2021-08-15T20:50:18+00:00"
"time": "2022-08-01T22:54:31+00:00"
},
{
"name": "fgrosse/phpasn1",
@ -249,16 +245,16 @@
},
{
"name": "pocketmine/bedrock-data",
"version": "1.7.0+bedrock-1.18.30",
"version": "1.9.0+bedrock-1.19.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockData.git",
"reference": "c8f323ff0cbdb36a5d95e7e4a23969f562445be0"
"reference": "ecd798a3e7ead50b7da73141bbb0c4ba14dd76a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/c8f323ff0cbdb36a5d95e7e4a23969f562445be0",
"reference": "c8f323ff0cbdb36a5d95e7e4a23969f562445be0",
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/ecd798a3e7ead50b7da73141bbb0c4ba14dd76a1",
"reference": "ecd798a3e7ead50b7da73141bbb0c4ba14dd76a1",
"shasum": ""
},
"type": "library",
@ -269,22 +265,22 @@
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
"support": {
"issues": "https://github.com/pmmp/BedrockData/issues",
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.18.30"
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.19.10"
},
"time": "2022-04-20T12:40:59+00:00"
"time": "2022-07-12T19:33:21+00:00"
},
{
"name": "pocketmine/bedrock-protocol",
"version": "9.0.2+bedrock-1.18.30",
"version": "11.0.4+bedrock-1.19.10",
"source": {
"type": "git",
"url": "https://github.com/pmmp/BedrockProtocol.git",
"reference": "37f1cd017caf7aaaa90330ee54690098283589cb"
"reference": "1c87aa1187bc7a31b4fc3e1c0f3e22251c2e6eab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/37f1cd017caf7aaaa90330ee54690098283589cb",
"reference": "37f1cd017caf7aaaa90330ee54690098283589cb",
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/1c87aa1187bc7a31b4fc3e1c0f3e22251c2e6eab",
"reference": "1c87aa1187bc7a31b4fc3e1c0f3e22251c2e6eab",
"shasum": ""
},
"require": {
@ -298,7 +294,7 @@
"ramsey/uuid": "^4.1"
},
"require-dev": {
"phpstan/phpstan": "1.7.4",
"phpstan/phpstan": "1.8.0",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpstan/phpstan-strict-rules": "^1.0.0",
"phpunit/phpunit": "^9.5"
@ -316,9 +312,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/9.0.2+bedrock-1.18.30"
"source": "https://github.com/pmmp/BedrockProtocol/tree/11.0.4+bedrock-1.19.10"
},
"time": "2022-05-30T15:09:53+00:00"
"time": "2022-07-24T19:22:18+00:00"
},
{
"name": "pocketmine/binaryutils",
@ -685,16 +681,16 @@
},
{
"name": "pocketmine/nbt",
"version": "0.3.2",
"version": "0.3.3",
"source": {
"type": "git",
"url": "https://github.com/pmmp/NBT.git",
"reference": "3e0d9ef6b6c5fb45e3745a121296e75631b3eefe"
"reference": "f4321be50df1a18b9f4e94d428a2e68a6e2ac2b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/3e0d9ef6b6c5fb45e3745a121296e75631b3eefe",
"reference": "3e0d9ef6b6c5fb45e3745a121296e75631b3eefe",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/f4321be50df1a18b9f4e94d428a2e68a6e2ac2b4",
"reference": "f4321be50df1a18b9f4e94d428a2e68a6e2ac2b4",
"shasum": ""
},
"require": {
@ -704,7 +700,7 @@
},
"require-dev": {
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "1.2.0",
"phpstan/phpstan": "1.7.7",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.5"
},
@ -721,9 +717,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/0.3.2"
"source": "https://github.com/pmmp/NBT/tree/0.3.3"
},
"time": "2021-12-16T01:02:37+00:00"
"time": "2022-07-06T14:13:26+00:00"
},
{
"name": "pocketmine/raklib",
@ -930,20 +926,20 @@
},
{
"name": "ramsey/uuid",
"version": "4.3.1",
"version": "4.4.0",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
"reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28"
"reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/8505afd4fea63b81a85d3b7b53ac3cb8dc347c28",
"reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/373f7bacfcf3de038778ff27dcce5672ddbf4c8a",
"reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a",
"shasum": ""
},
"require": {
"brick/math": "^0.8 || ^0.9",
"brick/math": "^0.8 || ^0.9 || ^0.10",
"ext-ctype": "*",
"ext-json": "*",
"php": "^8.0",
@ -959,7 +955,6 @@
"doctrine/annotations": "^1.8",
"ergebnis/composer-normalize": "^2.15",
"mockery/mockery": "^1.3",
"moontoast/math": "^1.1",
"paragonie/random-lib": "^2",
"php-mock/php-mock": "^2.2",
"php-mock/php-mock-mockery": "^1.3",
@ -1008,7 +1003,7 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.3.1"
"source": "https://github.com/ramsey/uuid/tree/4.4.0"
},
"funding": [
{
@ -1020,102 +1015,20 @@
"type": "tidelift"
}
],
"time": "2022-03-27T21:42:02+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-10-20T20:35:02+00:00"
"time": "2022-08-05T17:58:37+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.25.0",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"
"reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
"reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1",
"reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1",
"shasum": ""
},
"require": {
@ -1124,7 +1037,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1165,7 +1078,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0"
},
"funding": [
{
@ -1181,25 +1094,25 @@
"type": "tidelift"
}
],
"time": "2021-09-13T13:58:11+00:00"
"time": "2022-05-24T11:49:31+00:00"
},
{
"name": "webmozart/assert",
"version": "1.10.0",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"symfony/polyfill-ctype": "^1.8"
"ext-ctype": "*",
"php": "^7.2 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
@ -1237,9 +1150,9 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.10.0"
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
},
"time": "2021-03-09T10:59:23+00:00"
"time": "2022-06-03T18:03:27+00:00"
},
{
"name": "webmozart/path-util",
@ -1819,16 +1732,16 @@
},
{
"name": "phpstan/phpstan",
"version": "1.7.8",
"version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "2bf3d43015d56abac4d002a4d2d6c3a7d6fa627a"
"reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/2bf3d43015d56abac4d002a4d2d6c3a7d6fa627a",
"reference": "2bf3d43015d56abac4d002a4d2d6c3a7d6fa627a",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c",
"reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c",
"shasum": ""
},
"require": {
@ -1854,7 +1767,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/1.7.8"
"source": "https://github.com/phpstan/phpstan/tree/1.8.2"
},
"funding": [
{
@ -1874,7 +1787,7 @@
"type": "tidelift"
}
],
"time": "2022-06-01T13:43:17+00:00"
"time": "2022-07-20T09:57:31+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
@ -1930,21 +1843,21 @@
},
{
"name": "phpstan/phpstan-strict-rules",
"version": "1.2.3",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
"reference": "0c82c96f2a55d8b91bbc7ee6512c94f68a206b43"
"reference": "543675a9be82d4befb9ca0bd8cdc9d211665037f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/0c82c96f2a55d8b91bbc7ee6512c94f68a206b43",
"reference": "0c82c96f2a55d8b91bbc7ee6512c94f68a206b43",
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/543675a9be82d4befb9ca0bd8cdc9d211665037f",
"reference": "543675a9be82d4befb9ca0bd8cdc9d211665037f",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpstan/phpstan": "^1.6.3"
"phpstan/phpstan": "^1.7.15"
},
"require-dev": {
"nikic/php-parser": "^4.13.0",
@ -1972,9 +1885,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.2.3"
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.3.0"
},
"time": "2022-05-04T15:20:40+00:00"
"time": "2022-06-24T06:47:20+00:00"
},
{
"name": "phpunit/php-code-coverage",
@ -2296,16 +2209,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.20",
"version": "9.5.21",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba"
"reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba",
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e32b76be457de00e83213528f6bb37e2a38fcb1",
"reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1",
"shasum": ""
},
"require": {
@ -2339,7 +2252,6 @@
"sebastian/version": "^3.0.2"
},
"require-dev": {
"ext-pdo": "*",
"phpspec/prophecy-phpunit": "^2.0.1"
},
"suggest": {
@ -2383,7 +2295,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21"
},
"funding": [
{
@ -2395,7 +2307,7 @@
"type": "github"
}
],
"time": "2022-04-01T12:37:26+00:00"
"time": "2022-06-19T12:14:25+00:00"
},
{
"name": "sebastian/cli-parser",

View File

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

View File

@ -94,7 +94,8 @@ class Lava extends Liquid{
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4);
$entity->attack($ev);
$ev = new EntityCombustByBlockEvent($this, $entity, 15);
//in java burns entities for 15 seconds - seems to be a parity issue in bedrock
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
$ev->call();
if(!$ev->isCancelled()){
$entity->setOnFire($ev->getDuration());

View File

@ -56,7 +56,8 @@ class Skull extends Flowable{
}
public function readStateFromData(int $id, int $stateMeta) : void{
$this->facing = $stateMeta === 1 ? Facing::UP : BlockDataSerializer::readHorizontalFacing($stateMeta);
$facingMeta = $stateMeta & 0x7;
$this->facing = $facingMeta === 1 ? Facing::UP : BlockDataSerializer::readHorizontalFacing($facingMeta);
$this->noDrops = ($stateMeta & BlockLegacyMetadata::SKULL_FLAG_NO_DROPS) !== 0;
}

View File

@ -24,9 +24,6 @@ declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\block\Block;
use pocketmine\block\BlockLegacyIds;
use pocketmine\block\Fire;
use pocketmine\block\Liquid;
use pocketmine\block\VanillaBlocks;
use pocketmine\entity\Location;
use pocketmine\entity\object\FallingBlock;
@ -50,7 +47,7 @@ trait FallableTrait{
public function onNearbyBlockChange() : void{
$pos = $this->getPosition();
$down = $pos->getWorld()->getBlock($pos->getSide(Facing::DOWN));
if($down->getId() === BlockLegacyIds::AIR || $down instanceof Liquid || $down instanceof Fire){
if($down->canBeReplaced()){
$pos->getWorld()->setBlock($pos, VanillaBlocks::AIR());
$block = $this;

View File

@ -85,7 +85,7 @@ class FormattedCommandAlias extends Command{
$target->timings->startTiming();
try{
$target->execute($sender, $commandLabel, $args);
$target->execute($sender, $commandLabel, $commandArgs);
}catch(InvalidCommandSyntaxException $e){
$sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage())));
}finally{

View File

@ -522,6 +522,9 @@ abstract class Entity{
}
public function attack(EntityDamageEvent $source) : void{
if($this->isFireProof() && ($source->getCause() === EntityDamageEvent::CAUSE_FIRE || $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK)){
$source->cancel();
}
$source->call();
if($source->isCancelled()){
return;
@ -1461,6 +1464,7 @@ abstract class Entity{
$this->location->pitch,
$this->location->yaw,
$this->location->yaw, //TODO: head yaw
$this->location->yaw, //TODO: body yaw (wtf mojang?)
array_map(function(Attribute $attr) : NetworkAttribute{
return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue());
}, $this->attributeMap->getAll()),

View File

@ -48,9 +48,9 @@ use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\types\command\CommandPermissions;
use pocketmine\network\mcpe\protocol\types\DeviceOS;
use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
@ -58,11 +58,15 @@ use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty;
use pocketmine\network\mcpe\protocol\types\GameMode;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\UpdateAbilitiesPacketLayer;
use pocketmine\network\mcpe\protocol\UpdateAbilitiesPacket;
use pocketmine\player\Player;
use pocketmine\utils\Limits;
use pocketmine\world\sound\TotemUseSound;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use function array_fill;
use function array_filter;
use function array_key_exists;
use function array_merge;
@ -471,7 +475,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
$player->getNetworkSession()->sendDataPacket(AddPlayerPacket::create(
$this->getUniqueId(),
$this->getName(),
$this->getId(), //TODO: actor unique ID
$this->getId(),
"",
$this->location->asVector3(),
@ -482,7 +485,14 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand())),
GameMode::SURVIVAL,
$this->getAllNetworkData(),
AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->getId()), //TODO
UpdateAbilitiesPacket::create(CommandPermissions::NORMAL, PlayerPermissions::VISITOR, $this->getId() /* TODO: this should be unique ID */, [
new UpdateAbilitiesPacketLayer(
UpdateAbilitiesPacketLayer::LAYER_BASE,
array_fill(0, UpdateAbilitiesPacketLayer::NUMBER_OF_ABILITIES, false),
0.0,
0.0
)
]),
[], //TODO: entity links
"", //device ID (we intentionally don't send this - secvuln)
DeviceOS::UNKNOWN //we intentionally don't send this (secvuln)

View File

@ -85,14 +85,11 @@ class EffectManager{
$index = spl_object_id($effectType);
if(isset($this->effects[$index])){
$effect = $this->effects[$index];
$hasExpired = $effect->hasExpired();
$ev = new EntityEffectRemoveEvent($this->entity, $effect);
$ev->call();
if($ev->isCancelled()){
if($hasExpired && !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed
foreach($this->effectAddHooks as $hook){
$hook($ev->getEffect(), true);
}
foreach($this->effectAddHooks as $hook){
$hook($ev->getEffect(), true);
}
return;
}

View File

@ -30,7 +30,7 @@ use pocketmine\event\entity\EntityDamageEvent;
class WitherEffect extends Effect{
public function canTick(EffectInstance $instance) : bool{
if(($interval = (50 >> $instance->getAmplifier())) > 0){
if(($interval = (40 >> $instance->getAmplifier())) > 0){
return ($instance->getDuration() % $interval) === 0;
}
return true;

View File

@ -30,6 +30,7 @@ class PaintingMotive{
protected static $motives = [];
public static function init() : void{
self::$initialized = true;
foreach([
new PaintingMotive(1, 1, "Alban"),
new PaintingMotive(1, 1, "Aztec"),
@ -67,10 +68,16 @@ class PaintingMotive{
}
public static function registerMotive(PaintingMotive $motive) : void{
if(!self::$initialized){
self::init();
}
self::$motives[$motive->getName()] = $motive;
}
public static function getMotiveByName(string $name) : ?PaintingMotive{
if(!self::$initialized){
self::init();
}
return self::$motives[$name] ?? null;
}

View File

@ -23,7 +23,15 @@ declare(strict_types=1);
namespace pocketmine\item;
class FishingRod extends Item{
class FishingRod extends Durable{
public function getMaxStackSize() : int{
return 1;
}
public function getMaxDurability() : int{
return 384;
}
//TODO
}

View File

@ -100,8 +100,9 @@ class Item implements \JsonSerializable{
* Constructs a new Item type. This constructor should ONLY be used when constructing a new item TYPE to register
* into the index.
*
* NOTE: This should NOT BE USED for creating items to set into an inventory. Use {@link ItemFactory#get} for that
* NOTE: This should NOT BE USED for creating items to set into an inventory. Use VanillaItems for that
* purpose.
* @see VanillaItems
*/
public function __construct(ItemIdentifier $identifier, string $name = "Unknown"){
$this->identifier = $identifier;

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe;
use pocketmine\block\tile\Spawnable;
use pocketmine\data\bedrock\EffectIdMap;
use pocketmine\entity\Attribute;
use pocketmine\entity\effect\EffectInstance;
@ -57,8 +58,8 @@ use pocketmine\network\mcpe\handler\PacketHandler;
use pocketmine\network\mcpe\handler\PreSpawnPacketHandler;
use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler;
use pocketmine\network\mcpe\handler\SpawnResponsePacketHandler;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket;
@ -93,6 +94,7 @@ use pocketmine\network\mcpe\protocol\types\BlockPosition;
use pocketmine\network\mcpe\protocol\types\command\CommandData;
use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
use pocketmine\network\mcpe\protocol\types\command\CommandPermissions;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute;
use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty;
@ -100,9 +102,13 @@ use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\UpdateAbilitiesPacketLayer;
use pocketmine\network\mcpe\protocol\UpdateAbilitiesPacket;
use pocketmine\network\mcpe\protocol\UpdateAdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
use pocketmine\network\NetworkSessionManager;
use pocketmine\network\PacketHandlingException;
use pocketmine\permission\DefaultPermissionNames;
use pocketmine\permission\DefaultPermissions;
use pocketmine\player\GameMode;
use pocketmine\player\Player;
@ -250,8 +256,8 @@ class NetworkSession{
$permissionHooks = $this->player->getPermissionRecalculationCallbacks();
$permissionHooks->add($permHook = function() : void{
$this->logger->debug("Syncing available commands and adventure settings due to permission recalculation");
$this->syncAdventureSettings($this->player);
$this->logger->debug("Syncing available commands and abilities/permissions due to permission recalculation");
$this->syncAbilities($this->player);
$this->syncAvailableCommands();
});
$this->disposeHooks->add(static function() use ($permissionHooks, $permHook) : void{
@ -716,7 +722,7 @@ class NetworkSession{
$this->syncAttributes($this->player, $this->player->getAttributeMap()->getAll());
$this->player->sendData(null);
$this->syncAdventureSettings($this->player);
$this->syncAbilities($this->player);
$this->invManager->syncAll();
$this->setHandler(new InGamePacketHandler($this->player, $this, $this->invManager));
}
@ -766,37 +772,60 @@ class NetworkSession{
public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{
$this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->coreGameModeToProtocol($mode)));
if($this->player !== null){
$this->syncAdventureSettings($this->player);
$this->syncAbilities($this->player);
$this->syncAdventureSettings(); //TODO: we might be able to do this with the abilities packet alone
}
if(!$isRollback && $this->invManager !== null){
$this->invManager->syncCreative();
}
}
/**
* TODO: make this less specialized
*/
public function syncAdventureSettings(Player $for) : void{
public function syncAbilities(Player $for) : void{
$isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR);
$pk = AdventureSettingsPacket::create(
0,
$isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL,
0,
//ALL of these need to be set for the base layer, otherwise the client will cry
$boolAbilities = [
UpdateAbilitiesPacketLayer::ABILITY_ALLOW_FLIGHT => $for->getAllowFlight(),
UpdateAbilitiesPacketLayer::ABILITY_FLYING => $for->isFlying(),
UpdateAbilitiesPacketLayer::ABILITY_NO_CLIP => !$for->hasBlockCollision(),
UpdateAbilitiesPacketLayer::ABILITY_OPERATOR => $isOp,
UpdateAbilitiesPacketLayer::ABILITY_TELEPORT => $for->hasPermission(DefaultPermissionNames::COMMAND_TELEPORT),
UpdateAbilitiesPacketLayer::ABILITY_INVULNERABLE => $for->isCreative(),
UpdateAbilitiesPacketLayer::ABILITY_MUTED => false,
UpdateAbilitiesPacketLayer::ABILITY_WORLD_BUILDER => false,
UpdateAbilitiesPacketLayer::ABILITY_INFINITE_RESOURCES => !$for->hasFiniteResources(),
UpdateAbilitiesPacketLayer::ABILITY_LIGHTNING => false,
UpdateAbilitiesPacketLayer::ABILITY_BUILD => !$for->isSpectator(),
UpdateAbilitiesPacketLayer::ABILITY_MINE => !$for->isSpectator(),
UpdateAbilitiesPacketLayer::ABILITY_DOORS_AND_SWITCHES => !$for->isSpectator(),
UpdateAbilitiesPacketLayer::ABILITY_OPEN_CONTAINERS => !$for->isSpectator(),
UpdateAbilitiesPacketLayer::ABILITY_ATTACK_PLAYERS => !$for->isSpectator(),
UpdateAbilitiesPacketLayer::ABILITY_ATTACK_MOBS => !$for->isSpectator(),
];
$this->sendDataPacket(UpdateAbilitiesPacket::create(
$isOp ? CommandPermissions::OPERATOR : CommandPermissions::NORMAL,
$isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER,
0,
$for->getId()
);
$for->getId(),
[
//TODO: dynamic flying speed! FINALLY!!!!!!!!!!!!!!!!!
new UpdateAbilitiesPacketLayer(UpdateAbilitiesPacketLayer::LAYER_BASE, $boolAbilities, 0.05, 0.1),
]
));
}
$pk->setFlag(AdventureSettingsPacket::WORLD_IMMUTABLE, $for->isSpectator());
$pk->setFlag(AdventureSettingsPacket::NO_PVP, $for->isSpectator());
$pk->setFlag(AdventureSettingsPacket::AUTO_JUMP, $for->hasAutoJump());
$pk->setFlag(AdventureSettingsPacket::ALLOW_FLIGHT, $for->getAllowFlight());
$pk->setFlag(AdventureSettingsPacket::NO_CLIP, !$for->hasBlockCollision());
$pk->setFlag(AdventureSettingsPacket::FLYING, $for->isFlying());
//TODO: permission flags
$this->sendDataPacket($pk);
public function syncAdventureSettings() : void{
if($this->player === null){
throw new \LogicException("Cannot sync adventure settings for a player that is not yet created");
}
//everything except auto jump is handled via UpdateAbilitiesPacket
$this->sendDataPacket(UpdateAdventureSettingsPacket::create(
noAttackingMobs: false,
noAttackingPlayers: false,
worldImmutable: false,
showNameTags: true,
autoJump: $this->player->hasAutoJump()
));
}
/**
@ -932,6 +961,22 @@ class NetworkSession{
try{
$this->queueCompressed($promise);
$onCompletion();
//TODO: HACK! we send the full tile data here, due to a bug in 1.19.10 which causes items in tiles
//(item frames, lecterns) to not load properly when they are sent in a chunk via the classic chunk
//sending mechanism. We workaround this bug by sending only bare essential data in LevelChunkPacket
//(enough to create the tiles, since BlockActorDataPacket can't create tiles by itself) and then
//send the actual tile properties here.
//TODO: maybe we can stuff these packets inside the cached batch alongside LevelChunkPacket?
$chunk = $currentWorld->getChunk($chunkX, $chunkZ);
if($chunk !== null){
foreach($chunk->getTiles() as $tile){
if(!($tile instanceof Spawnable)){
continue;
}
$this->sendDataPacket(BlockActorDataPacket::create(BlockPosition::fromVector3($tile->getPosition()), $tile->getSerializedSpawnCompound()));
}
}
}finally{
$world->timings->syncChunkSend->stopTiming();
}

View File

@ -234,6 +234,9 @@ class TypeConverter{
$compound = null;
}
}
if($id < -0x8000 || $id >= 0x7fff){
throw new TypeConversionException("Item ID must be in range " . -0x8000 . " ... " . 0x7fff . " (received $id)");
}
if($meta < 0 || $meta >= 0x7fff){ //this meta value may have been restored from the NBT
throw new TypeConversionException("Item meta must be in range 0 ... " . 0x7fff . " (received $meta)");
}

View File

@ -80,6 +80,7 @@ use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket;
use pocketmine\network\mcpe\protocol\PlayerHotbarPacket;
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\RequestAbilityPacket;
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket;
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
@ -114,6 +115,7 @@ use function count;
use function fmod;
use function implode;
use function in_array;
use function is_bool;
use function is_infinite;
use function is_nan;
use function json_decode;
@ -143,6 +145,11 @@ class InGamePacketHandler extends PacketHandler{
/** @var UseItemTransactionData|null */
protected $lastRightClickData = null;
protected ?Vector3 $lastPlayerAuthInputPosition = null;
protected ?float $lastPlayerAuthInputYaw = null;
protected ?float $lastPlayerAuthInputPitch = null;
protected ?int $lastPlayerAuthInputFlags = null;
/** @var bool */
public $forceMoveSync = false;
@ -166,9 +173,10 @@ class InGamePacketHandler extends PacketHandler{
return true;
}
private function resolveOnOffInputFlags(PlayerAuthInputPacket $packet, int $startFlag, int $stopFlag) : ?bool{
$enabled = $packet->hasFlag($startFlag);
if($enabled !== $packet->hasFlag($stopFlag)){
private function resolveOnOffInputFlags(int $inputFlags, int $startFlag, int $stopFlag) : ?bool{
$enabled = ($inputFlags & (1 << $startFlag)) !== 0;
$disabled = ($inputFlags & (1 << $stopFlag)) !== 0;
if($enabled !== $disabled){
return $enabled;
}
//neither flag was set, or both were set
@ -177,51 +185,68 @@ class InGamePacketHandler extends PacketHandler{
public function handlePlayerAuthInput(PlayerAuthInputPacket $packet) : bool{
$rawPos = $packet->getPosition();
foreach([$rawPos->x, $rawPos->y, $rawPos->z, $packet->getYaw(), $packet->getHeadYaw(), $packet->getPitch()] as $float){
$rawYaw = $packet->getYaw();
$rawPitch = $packet->getPitch();
foreach([$rawPos->x, $rawPos->y, $rawPos->z, $rawYaw, $packet->getHeadYaw(), $rawPitch] as $float){
if(is_infinite($float) || is_nan($float)){
$this->session->getLogger()->debug("Invalid movement received, contains NAN/INF components");
return false;
}
}
$yaw = fmod($packet->getYaw(), 360);
$pitch = fmod($packet->getPitch(), 360);
if($yaw < 0){
$yaw += 360;
if($rawYaw !== $this->lastPlayerAuthInputYaw || $rawPitch !== $this->lastPlayerAuthInputPitch){
$this->lastPlayerAuthInputYaw = $rawYaw;
$this->lastPlayerAuthInputPitch = $rawPitch;
$yaw = fmod($rawYaw, 360);
$pitch = fmod($rawPitch, 360);
if($yaw < 0){
$yaw += 360;
}
$this->player->setRotation($yaw, $pitch);
}
$this->player->setRotation($yaw, $pitch);
$curPos = $this->player->getLocation();
$hasMoved = $this->lastPlayerAuthInputPosition === null || !$this->lastPlayerAuthInputPosition->equals($rawPos);
$newPos = $rawPos->round(4)->subtract(0, 1.62, 0);
if($this->forceMoveSync && $newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
$this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos);
//Still getting movements from before teleport, ignore them
return false;
if($this->forceMoveSync && $hasMoved){
$curPos = $this->player->getLocation();
if($newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
$this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos);
//Still getting movements from before teleport, ignore them
return false;
}
// Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock
$this->forceMoveSync = false;
}
// Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock
$this->forceMoveSync = false;
$inputFlags = $packet->getInputFlags();
if($inputFlags !== $this->lastPlayerAuthInputFlags){
$this->lastPlayerAuthInputFlags = $inputFlags;
$sneaking = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SNEAKING, PlayerAuthInputFlags::STOP_SNEAKING);
$sprinting = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SPRINTING, PlayerAuthInputFlags::STOP_SPRINTING);
$swimming = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SWIMMING, PlayerAuthInputFlags::STOP_SWIMMING);
$gliding = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_GLIDING, PlayerAuthInputFlags::STOP_GLIDING);
$mismatch =
($sneaking !== null && !$this->player->toggleSneak($sneaking)) |
($sprinting !== null && !$this->player->toggleSprint($sprinting)) |
($swimming !== null && !$this->player->toggleSwim($swimming)) |
($gliding !== null && !$this->player->toggleGlide($gliding));
if((bool) $mismatch){
$this->player->sendData([$this->player]);
$sneaking = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SNEAKING, PlayerAuthInputFlags::STOP_SNEAKING);
$sprinting = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SPRINTING, PlayerAuthInputFlags::STOP_SPRINTING);
$swimming = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SWIMMING, PlayerAuthInputFlags::STOP_SWIMMING);
$gliding = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_GLIDING, PlayerAuthInputFlags::STOP_GLIDING);
$mismatch =
($sneaking !== null && !$this->player->toggleSneak($sneaking)) |
($sprinting !== null && !$this->player->toggleSprint($sprinting)) |
($swimming !== null && !$this->player->toggleSwim($swimming)) |
($gliding !== null && !$this->player->toggleGlide($gliding));
if((bool) $mismatch){
$this->player->sendData([$this->player]);
}
if($packet->hasFlag(PlayerAuthInputFlags::START_JUMPING)){
$this->player->jump();
}
}
if($packet->hasFlag(PlayerAuthInputFlags::START_JUMPING)){
$this->player->jump();
}
if(!$this->forceMoveSync){
if(!$this->forceMoveSync && $hasMoved){
$this->lastPlayerAuthInputPosition = $rawPos;
//TODO: this packet has WAYYYYY more useful information that we're not using
$this->player->handleMovement($newPos);
}
@ -267,7 +292,6 @@ class InGamePacketHandler extends PacketHandler{
//TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier)
return $packet->actorRuntimeId === ActorEvent::EATING_ITEM;
}
$this->player->removeCurrentWindow();
switch($packet->eventId){
case ActorEvent::EATING_ITEM: //TODO: ignore this and handle it server-side
@ -610,6 +634,10 @@ class InGamePacketHandler extends PacketHandler{
case PlayerAction::CREATIVE_PLAYER_DESTROY_BLOCK:
//TODO: do we need to handle this?
break;
case PlayerAction::START_ITEM_USE_ON:
case PlayerAction::STOP_ITEM_USE_ON:
//TODO: this has no obvious use and seems only used for analytics in vanilla - ignore it
break;
default:
$this->session->getLogger()->debug("Unhandled/unknown player action type " . $action);
return false;
@ -642,23 +670,7 @@ class InGamePacketHandler extends PacketHandler{
}
public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{
if($packet->targetActorUniqueId !== $this->player->getId()){
return false; //TODO: operators can change other people's permissions using this
}
$handled = false;
$isFlying = $packet->getFlag(AdventureSettingsPacket::FLYING);
if($isFlying !== $this->player->isFlying()){
if(!$this->player->toggleFlight($isFlying)){
$this->session->syncAdventureSettings($this->player);
}
$handled = true;
}
//TODO: check for other changes
return $handled;
return true; //no longer used, but the client still sends it for flight changes
}
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
@ -980,4 +992,22 @@ class InGamePacketHandler extends PacketHandler{
$this->player->emote($packet->getEmoteId());
return true;
}
public function handleRequestAbility(RequestAbilityPacket $packet) : bool{
if($packet->getAbilityId() === RequestAbilityPacket::ABILITY_FLYING){
$isFlying = $packet->getAbilityValue();
if(!is_bool($isFlying)){
throw new PacketHandlingException("Flying ability should always have a bool value");
}
if($isFlying !== $this->player->isFlying()){
if(!$this->player->toggleFlight($isFlying)){
$this->session->syncAbilities($this->player);
}
}
return true;
}
return false;
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\handler;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\cache\CraftingDataCache;
use pocketmine\network\mcpe\cache\StaticPacketCache;
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
@ -33,6 +34,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\types\BlockPosition;
use pocketmine\network\mcpe\protocol\types\BoolGameRule;
use pocketmine\network\mcpe\protocol\types\CacheableNbt;
use pocketmine\network\mcpe\protocol\types\DimensionIds;
use pocketmine\network\mcpe\protocol\types\Experiments;
use pocketmine\network\mcpe\protocol\types\LevelSettings;
@ -42,6 +44,7 @@ use pocketmine\network\mcpe\protocol\types\SpawnSettings;
use pocketmine\player\Player;
use pocketmine\Server;
use pocketmine\VersionInfo;
use Ramsey\Uuid\Uuid;
use function sprintf;
/**
@ -82,6 +85,7 @@ class PreSpawnPacketHandler extends PacketHandler{
$this->player->getOffsetPosition($location),
$location->pitch,
$location->yaw,
new CacheableNbt(CompoundTag::create()), //TODO: we don't care about this right now
$levelSettings,
"",
$this->server->getMotd(),
@ -93,6 +97,7 @@ class PreSpawnPacketHandler extends PacketHandler{
"",
false,
sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)),
Uuid::fromString(Uuid::NIL),
[],
0,
GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries()
@ -102,7 +107,8 @@ class PreSpawnPacketHandler extends PacketHandler{
$this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs());
$this->session->syncAttributes($this->player, $this->player->getAttributeMap()->getAll());
$this->session->syncAvailableCommands();
$this->session->syncAdventureSettings($this->player);
$this->session->syncAbilities($this->player);
$this->session->syncAdventureSettings();
foreach($this->player->getEffects()->all() as $effect){
$this->session->onEntityEffectAdded($this->player, $effect, false);
}

View File

@ -24,8 +24,11 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe\serializer;
use pocketmine\block\tile\Spawnable;
use pocketmine\block\tile\Tile;
use pocketmine\block\tile\TileFactory;
use pocketmine\data\bedrock\BiomeIds;
use pocketmine\data\bedrock\LegacyBiomeIdToStringIdMap;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\TreeRoot;
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
@ -38,6 +41,7 @@ use pocketmine\world\format\PalettedBlockArray;
use pocketmine\world\format\SubChunk;
use function chr;
use function count;
use function get_class;
use function str_repeat;
final class ChunkSerializer{
@ -125,9 +129,19 @@ final class ChunkSerializer{
public static function serializeTiles(Chunk $chunk) : string{
$stream = new BinaryStream();
$nbtSerializer = new NetworkNbtSerializer();
foreach($chunk->getTiles() as $tile){
if($tile instanceof Spawnable){
$stream->put($tile->getSerializedSpawnCompound()->getEncodedNbt());
//TODO: HACK! we send only the bare essentials to create a tile in the chunk itself, due to a bug in
//1.19.10 which causes items in tiles (item frames, lecterns) to not load properly when they are sent in
//a chunk via the classic chunk sending mechanism. We workaround this bug by sendingBlockActorDataPacket
//in NetworkSession to set the actual tile properties after sending the LevelChunkPacket.
$nbt = CompoundTag::create()
->setString(Tile::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($tile)))
->setInt(Tile::TAG_X, $tile->getPosition()->getFloorX())
->setInt(Tile::TAG_Y, $tile->getPosition()->getFloorY())
->setInt(Tile::TAG_Z, $tile->getPosition()->getFloorZ());
$stream->put($nbtSerializer->write(new TreeRoot($nbt)));
}
}

View File

@ -421,7 +421,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
public function setAllowFlight(bool $value) : void{
if($this->allowFlight !== $value){
$this->allowFlight = $value;
$this->getNetworkSession()->syncAdventureSettings($this);
$this->getNetworkSession()->syncAbilities($this);
}
}
@ -432,7 +432,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
public function setHasBlockCollision(bool $value) : void{
if($this->blockCollision !== $value){
$this->blockCollision = $value;
$this->getNetworkSession()->syncAdventureSettings($this);
$this->getNetworkSession()->syncAbilities($this);
}
}
@ -444,7 +444,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
if($this->flying !== $value){
$this->flying = $value;
$this->resetFallDistance();
$this->getNetworkSession()->syncAdventureSettings($this);
$this->getNetworkSession()->syncAbilities($this);
}
}
@ -455,7 +455,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
public function setAutoJump(bool $value) : void{
if($this->autoJump !== $value){
$this->autoJump = $value;
$this->getNetworkSession()->syncAdventureSettings($this);
$this->getNetworkSession()->syncAdventureSettings();
}
}
@ -1180,7 +1180,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
return;
}
$oldPos = $this->getLocation();
$oldPos = $this->location;
$distanceSquared = $newPos->distanceSquared($oldPos);
$revert = false;
@ -1198,7 +1198,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* asking for help if you suffer the consequences of messing with this.
*/
$this->logger->debug("Moved too fast, reverting movement");
$this->logger->debug("Old position: " . $this->location->asVector3() . ", new position: " . $newPos);
$this->logger->debug("Old position: " . $oldPos->asVector3() . ", new position: " . $newPos);
$revert = true;
}elseif(!$this->getWorld()->isInLoadedTerrain($newPos)){
$revert = true;
@ -1206,9 +1206,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
}
if(!$revert && $distanceSquared != 0){
$dx = $newPos->x - $this->location->x;
$dy = $newPos->y - $this->location->y;
$dz = $newPos->z - $this->location->z;
$dx = $newPos->x - $oldPos->x;
$dy = $newPos->y - $oldPos->y;
$dz = $newPos->z - $oldPos->z;
$this->move($dx, $dy, $dz);
}
@ -2339,6 +2339,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
parent::syncNetworkData($properties);
$properties->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1);
$properties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, $this->hasBlockCollision());
$properties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null);
$properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping !== null ? BlockPosition::fromVector3($this->sleeping) : new BlockPosition(0, 0, 0));

View File

@ -33,19 +33,31 @@ use function spl_object_id;
/**
* Class used to run async tasks in other threads.
*
* An AsyncTask does not have its own thread. It is queued into an AsyncPool and executed if there is an async worker
* with no AsyncTask running. Therefore, an AsyncTask SHOULD NOT execute for more than a few seconds. For tasks that
* run for a long time or infinitely, start another thread instead.
* An AsyncTask is run by a thread pool of reusable threads, and doesn't have its own dedicated thread. A thread is
* usually chosen from the pool at random to run the task (though a specific thread in the pool may be selected
* manually, if needed).
* Reusing threads this way has a much lower performance cost than starting an entirely new thread for every operation.
* AsyncTasks are therefore suitable for brief CPU-bound tasks, such as world generation, compression/decompression of
* data, etc.
*
* AsyncTask SHOULD NOT be used for I/O-bound tasks, such as network I/O, file I/O, database I/O, etc. The server's
* central AsyncPool is used for things like compressing network packets for sending, so using AsyncTask for I/O will
* slow the whole server down, stall chunk loading, etc.
*
* An AsyncTask SHOULD NOT run for more than a few seconds. For tasks that run for a long time or indefinitely, create
* a dedicated thread instead.
*
* The Server instance is not accessible inside {@link AsyncTask::onRun()}. It can only be accessed in the main server
* thread, e.g. during {@link AsyncTask::onCompletion()} or {@link AsyncTask::onProgressUpdate()}. This means that
* whatever you do in onRun() must be able to work without the Server instance.
*
* WARNING: Any non-Threaded objects WILL BE SERIALIZED when assigned to members of AsyncTasks or other Threaded object.
* If later accessed from said Threaded object, you will be operating on a COPY OF THE OBJECT, NOT THE ORIGINAL OBJECT.
* If you want to store non-serializable objects to access when the task completes, store them using
* {@link AsyncTask::storeLocal}.
*
* WARNING: As of pthreads v3.1.6, arrays are converted to Volatile objects when assigned as members of Threaded objects.
* WARNING: Arrays are converted to Volatile objects when assigned as members of Threaded objects.
* Keep this in mind when using arrays stored as members of your AsyncTask.
*
* WARNING: Do not call PocketMine-MP API methods from other Threads!!
*/
abstract class AsyncTask extends \Threaded{
/**

View File

@ -38,6 +38,7 @@ class ReversePriorityQueue extends \SplPriorityQueue{
*
* @return int
*/
#[\ReturnTypeWillChange]
public function compare($priority1, $priority2){
//TODO: this will crash if non-numeric priorities are used
return (int) -($priority1 - $priority2);

View File

@ -23,25 +23,20 @@ declare(strict_types=1);
namespace pocketmine\world\particle;
use pocketmine\block\VanillaBlocks;
use pocketmine\entity\Entity;
use pocketmine\entity\Skin;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\convert\SkinAdapterSingleton;
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\types\DeviceOS;
use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty;
use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty;
use pocketmine\network\mcpe\protocol\types\entity\IntMetadataProperty;
use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty;
use pocketmine\network\mcpe\protocol\types\GameMode;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStack;
use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use Ramsey\Uuid\Uuid;
use function str_repeat;
use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty;
class FloatingTextParticle implements Particle{
//TODO: HACK!
@ -94,39 +89,34 @@ class FloatingTextParticle implements Particle{
}
if(!$this->invisible){
$uuid = Uuid::uuid4();
$name = $this->title . ($this->text !== "" ? "\n" . $this->text : "");
$p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, SkinAdapterSingleton::get()->toSkinData(new Skin("Standard_Custom", str_repeat("\x00", 8192))))]);
$actorFlags = (
1 << EntityMetadataFlags::IMMOBILE
);
$actorMetadata = [
EntityMetadataProperties::FLAGS => new LongMetadataProperty($actorFlags),
EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01) //zero causes problems on debug builds
EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01), //zero causes problems on debug builds
EntityMetadataProperties::BOUNDING_BOX_WIDTH => new FloatMetadataProperty(0.0),
EntityMetadataProperties::BOUNDING_BOX_HEIGHT => new FloatMetadataProperty(0.0),
EntityMetadataProperties::NAMETAG => new StringMetadataProperty($name),
EntityMetadataProperties::VARIANT => new IntMetadataProperty(RuntimeBlockMapping::getInstance()->toRuntimeId(VanillaBlocks::AIR()->getFullId())),
EntityMetadataProperties::ALWAYS_SHOW_NAMETAG => new ByteMetadataProperty(1),
];
$p[] = AddPlayerPacket::create(
$uuid,
$name,
$p[] = AddActorPacket::create(
$this->entityId, //TODO: actor unique ID
$this->entityId,
"",
$pos, //TODO: check offset
EntityIds::FALLING_BLOCK,
$pos, //TODO: check offset (0.49?)
null,
0,
0,
0,
ItemStackWrapper::legacy(ItemStack::null()),
GameMode::SURVIVAL,
$actorMetadata,
AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->entityId),
0,
[],
"",
DeviceOS::UNKNOWN
$actorMetadata,
[]
);
$p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]);
}
return $p;

View File

@ -25,6 +25,7 @@ namespace pocketmine\world\particle;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\convert\ItemTranslator;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\types\ParticleIds;
@ -32,6 +33,7 @@ class ItemBreakParticle implements Particle{
public function __construct(private Item $item){}
public function encode(Vector3 $pos) : array{
return [LevelEventPacket::standardParticle(ParticleIds::ITEM_BREAK, ($this->item->getId() << 16) | $this->item->getMeta(), $pos)];
[$id, $meta] = ItemTranslator::getInstance()->toNetworkId($this->item->getId(), $this->item->getMeta());
return [LevelEventPacket::standardParticle(ParticleIds::ITEM_BREAK, ($id << 16) | $meta, $pos)];
}
}

View File

@ -131,7 +131,7 @@ parameters:
path: ../../../src/block/DragonEgg.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int\\<0, max\\> given\\.$#"
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int\\<0, 255\\> given\\.$#"
count: 1
path: ../../../src/block/DragonEgg.php
@ -335,21 +335,6 @@ parameters:
count: 3
path: ../../../src/block/Mycelium.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/block/RedMushroom.php
-
message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/block/RedMushroom.php
-
message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
path: ../../../src/block/RedMushroom.php
-
message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#"
count: 1
@ -701,7 +686,7 @@ parameters:
path: ../../../src/network/mcpe/NetworkSession.php
-
message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#"
message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAbilities\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#"
count: 2
path: ../../../src/network/mcpe/NetworkSession.php

View File

@ -5,11 +5,6 @@ parameters:
count: 1
path: ../../../src/block/BaseBanner.php
-
message: "#^Property pocketmine\\\\block\\\\tile\\\\TileFactory\\:\\:\\$saveNames \\(array\\<class\\-string\\<pocketmine\\\\block\\\\tile\\\\Tile\\>, string\\>\\) does not accept array\\<class\\-string\\<pocketmine\\\\block\\\\tile\\\\Tile\\>, bool\\|string\\>\\.$#"
count: 1
path: ../../../src/block/tile/TileFactory.php
-
message: "#^Comparison operation \"\\<\" between int\\<1, max\\> and 1 is always false\\.$#"
count: 1
@ -80,11 +75,6 @@ parameters:
count: 1
path: ../../../src/thread/Worker.php
-
message: "#^Dead catch \\- JsonException is never thrown in the try block\\.$#"
count: 1
path: ../../../src/utils/Config.php
-
message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#"
count: 2

File diff suppressed because one or more lines are too long