Compare commits

..

44 Commits
3.8.5 ... 3.9.2

Author SHA1 Message Date
7a747d6f93 Release 3.9.2 2019-07-22 17:28:33 +01:00
e93d034a4e fix bucket empty sound position, close #3051 2019-07-22 17:17:15 +01:00
5a08a10448 update dependency requirements 2019-07-22 17:15:18 +01:00
622f93df45 remove usages of deprecated {} string access, closes #3035 2019-07-22 16:39:33 +01:00
b788982d60 Item: fixed setCustomName() not removing display NBT tag with empty name (#3049) 2019-07-19 20:07:53 +01:00
26faf4a952 Player: fixed sendTranslation() passing parent parameters to translate parameters 2019-07-19 18:15:35 +01:00
670bf2b9d1 doxygen: sort more things, for our sanity (#3045) 2019-07-19 10:52:32 +01:00
f5491346ce doxygen: set HIDE_IN_BODY_DOCS = yes (#3044)
fixes #3043
2019-07-19 10:34:41 +01:00
73d3f9f7f7 Fix loadbefore sometimes not working (#3040)
loadbefore operates by injecting self into the target plugin's soft-dependencies. The problem is that these soft-dependency lists are overwritten if the target plugin's soft-dependencies are resolved after the loadbefore of the origin plugin.
2019-07-17 16:52:29 +01:00
d874be99a6 PrimedTNT: fix explosion position, close #3037 2019-07-16 13:55:31 +01:00
1767cbe80d Player: Lower moved-too-fast warning and illegal-move warning to debug
many users have complained that this spams their consoles and they can't turn it off.
2019-07-16 13:51:38 +01:00
64fbf5025a 3.9.2 is next 2019-07-14 19:10:29 +01:00
aaa01bb6f8 Release 3.9.1 2019-07-14 19:10:29 +01:00
50d71809e1 Entity: fixed onfire flag being set when setting fire ticks to zero, closes #3031 2019-07-14 19:03:06 +01:00
6839712394 added new PlayerActionPacket constant, silence debug noise every time a player clicks a block 2019-07-14 17:30:37 +01:00
9b5ae7ec75 regenerate LevelSoundEventPacket sound IDs 2019-07-14 17:28:29 +01:00
94eb64c2be 1.12: fix resource packs, closes #3023 2019-07-14 17:22:44 +01:00
3fae57508b update particle ids 2019-07-13 20:08:17 +01:00
a883c35fd0 clean up yesterday's mess 2019-07-13 18:15:14 +01:00
740398282f [ci skip] added some detail about packet changes in 3.9.0 release 2019-07-13 15:35:00 +01:00
9d14bc54d6 3.9.1 is next 2019-07-12 19:03:24 +01:00
bd69c66d03 Release 3.9.0 2019-07-12 19:03:23 +01:00
c58a1bf9b7 Protocol changes for 1.12.0.28 2019-07-12 19:00:15 +01:00
59c310b914 unfuck the make-release script 2019-07-12 18:59:54 +01:00
790fcc4ebb Release 3.8.7 2019-07-12 18:20:47 +01:00
5430f19e7a make-release: allow specifying a version number explicitly 2019-07-12 18:18:26 +01:00
1cf4cf8614 Fixed decoding entries in SetScorePacket
closes #3000
2019-07-09 15:49:24 +01:00
55cccff850 Player: fixed documentation of isValidUserName()
[ci skip]
2019-07-07 23:50:59 +01:00
03e70e68f4 Player: fixed documentation of getDisplayName()
[ci skip]
2019-07-07 23:49:11 +01:00
7c52b4c93d make-release: added a missing newline 2019-07-07 18:02:25 +01:00
3f31dbde57 3.8.7 is next 2019-07-07 17:49:37 +01:00
1bfd6f2a90 Release 3.8.6 2019-07-07 17:49:37 +01:00
c7a5b8b0b4 Fixed noDamageTicks not preventing damage when last damage cause is null
noDamageTicks should make the entity completely invulnerable while active.
2019-07-07 17:37:52 +01:00
11fc16617a Liquid: fix max cost calculation for flow direction search, closes #2995 2019-07-07 14:32:52 +01:00
77a4393c7b Fixed possible out-of-bounds access on corrupted playerdata when loading inventory contents 2019-07-06 19:39:07 +01:00
f714ed6e90 Generator: fixed incorrect negative seed parsing in convertSeed() 2019-07-05 19:20:21 +01:00
7fc45bc5c3 partial fix for #2986 2019-07-04 18:18:42 +01:00
ab4b1be363 add constants for boat action of AnimatePacket
closes #2991
2019-07-03 16:30:45 +01:00
3c7f68dc1e Fix Entity::isNameTagAlwaysVisible() was returning the wrong value (#2990)
* Fix Entity::isNameTagAlwaysVisible() was returning the wrong value

* "> 0" to "=== 1"
2019-07-02 10:44:41 +01:00
15fa1056b7 added make-release script 2019-06-25 18:03:48 +01:00
feac2df088 readme: point to /plugins on poggit
[ci skip]
2019-06-25 13:11:36 +01:00
4c2015fd0f Update README.md
[ci skip]
2019-06-25 10:48:11 +01:00
16482e6a95 Update README.md
[ci skip]
2019-06-25 10:46:44 +01:00
ae9115ad0d 3.8.6 is next 2019-06-24 14:55:38 +01:00
86 changed files with 1839 additions and 716 deletions

View File

@ -9,7 +9,7 @@
- [Documentation](http://pmmp.readthedocs.org/) - [Documentation](http://pmmp.readthedocs.org/)
- [Installation instructions](https://pmmp.readthedocs.io/en/rtfd/installation.html) - [Installation instructions](https://pmmp.readthedocs.io/en/rtfd/installation.html)
- [Docker image](https://hub.docker.com/r/pmmp/pocketmine-mp) - [Docker image](https://hub.docker.com/r/pmmp/pocketmine-mp)
- [Plugin repository](https://poggit.pmmp.io) - [Plugin repository](https://poggit.pmmp.io/plugins)
### Discussion ### Discussion
- [Forums](https://forums.pmmp.io/) - [Forums](https://forums.pmmp.io/)
@ -22,8 +22,8 @@
* [Contributing Guidelines](CONTRIBUTING.md) * [Contributing Guidelines](CONTRIBUTING.md)
### Donate ### Donate
- Bitcoin Cash (BCH): `qz9p8dqkv0r7aahdatu5uewqfkvstrglv58f8yle07` - Bitcoin Cash (BCH): `qq3r46hn6ljnhnqnfwxt5pg3g447eq9jhvw5ddfear`
- Bitcoin (BTC): `1PVAyDJ2g7kcjCxAC3C89oxpV2ZYcLad8T` - Bitcoin (BTC): `171u8K9e4FtU6j3e5sqNoxKUgEw9qWQdRV`
- [Patreon](https://www.patreon.com/pocketminemp) - [Patreon](https://www.patreon.com/pocketminemp)
## Licensing information ## Licensing information

81
build/make-release.php Normal file
View File

@ -0,0 +1,81 @@
<?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\build_script;
use pocketmine\utils\VersionString;
use function dirname;
use function fgets;
use function file_get_contents;
use function file_put_contents;
use function preg_quote;
use function preg_replace;
use function sleep;
use function sprintf;
use function system;
use const pocketmine\BASE_VERSION;
use const STDIN;
require_once dirname(__DIR__) . '/src/pocketmine/VersionInfo.php';
require_once dirname(__DIR__) . '/vendor/autoload.php';
if(isset($argv[1])){
$currentVer = new VersionString($argv[1]);
}else{
$currentVer = new VersionString(BASE_VERSION);
}
$nextVer = new VersionString(sprintf(
"%u.%u.%u",
$currentVer->getMajor(),
$currentVer->getMinor(),
$currentVer->getPatch() + 1
));
function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{
$versionInfo = file_get_contents($versionInfoPath);
$versionInfo = preg_replace(
$pattern = '/^const BASE_VERSION = "(\d+)\.(\d+)\.(\d+)(?:-(.*))?";$/m',
'const BASE_VERSION = "' . $newVersion . '";',
$versionInfo
);
$versionInfo = preg_replace(
'/^const IS_DEVELOPMENT_BUILD = (?:true|false);$/m',
'const IS_DEVELOPMENT_BUILD = ' . ($isDev ? 'true' : 'false'). ';',
$versionInfo
);
file_put_contents($versionInfoPath, $versionInfo);
}
$versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php';
replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false);
echo "please add appropriate notes to the changelog and press enter...";
fgets(STDIN);
system('git add "' . dirname(__DIR__) . '/changelogs"');
system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"');
system('git tag ' . $currentVer->getBaseVersion());
replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true);
system('git add "' . $versionInfoPath . '"');
system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"');
echo "pushing changes in 10 seconds\n";
sleep(10);
system('git push origin HEAD ' . $currentVer->getBaseVersion());

View File

@ -55,3 +55,15 @@ This changelog **does not account for protocol changes**. If your plugin uses th
- Fixed sluggish playercount updating on MOTD. - Fixed sluggish playercount updating on MOTD.
- Added new MultiRecipe UUIDs. - Added new MultiRecipe UUIDs.
- Added an extra field to `StartGamePacket` to resolve minor incompatibility issues on different 1.11.x patch versions. - Added an extra field to `StartGamePacket` to resolve minor incompatibility issues on different 1.11.x patch versions.
# 3.8.6
- Fixed `Entity->isNameTagAlwaysVisible()` not working.
- Log messages are now cleaned of invalid UTF-8 sequences before emitting them.
- Fixed negative integers being considered as strings for world seeds.
- Fixed out-of-bounds access on invalid inventory data in player data saves.
- Fixed crash when custom liquids have flow decays which aren't factors of 4.
- Fixed `Entity->noDamageTicks` not working when the entity had no previous damage cause.
# 3.8.7
- Improved documentation of `Player->getDisplayName()` and `Player::isValidUserName()`.
- Fixed a bug in `SetScorePacket` decoding causing the entry list to always be empty.

54
changelogs/3.9.md Normal file
View File

@ -0,0 +1,54 @@
**For Minecraft: Bedrock Edition 1.12.0**
### Note about API versions
Plugins which don't touch the protocol and compatible with any previous 3.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.
# 3.9.0
- Added support for Minecraft: Bedrock Edition 1.12.0
- Removed compatibility with 1.11.0
## Protocol
- The following classes in the `\pocketmine\network\mcpe\protocol` namespace have been renamed:
- `AddEntityPacket` -> `AddActorPacket`
- `AddItemEntityPacket` -> `AddItemActorPacket`
- `AvailableEntityIdentifiersPacket` -> `AvailableActorIdentifiersPacket`
- `BlockEntityDataPacket` -> `BlockActorDataPacket`
- `EntityEventPacket` -> `ActorEventPacket`
- `EntityFallPacket` -> `ActorFallPacket`
- `EntityPickRequestPacket` -> `ActorPickRequestPacket`
- `MoveEntityAbsolutePacket` -> `MoveActorAbsolutePacket`
- `MoveEntityDeltaPacket` -> `MoveActorDeltaPacket`
- `RemoveEntityPacket` -> `RemoveActorPacket`
- `SetEntityDataPacket` -> `SetActorDataPacket`
- `SetEntityLinkPacket` -> `SetActorLinkPacket`
- `SetEntityMotionPacket` -> `SetActorMotionPacket`
- `TakeItemEntityPacket` -> `TakeItemActorPacket`
- The following classes in the `\pocketmine\network\mcpe\protocol` namespace have been removed:
- `FullChunkDataPacket`
- The following classes in the `\pocketmine\network\mcpe\protocol` namespace have been added:
- `AddEntityPacket` (not to be confused with the old one)
- `ClientCacheBlobStatusPacket`
- `ClientCacheMissResponsePacket`
- `ClientCacheStatusPacket`
- `LevelChunkPacket`
- `RemoveEntityPacket` (not to be confused with the old one)
- `StructureTemplateDataExportRequestPacket`
- `StructureTemplateDataExportResponsePacket`
# 3.9.1
- Fixed resource packs not working on 1.12 clients.
- Fixed some particles displaying incorrectly (some still don't render at all).
- Fixed `Entity->setFireTicks()` with a value of `0` setting the on-fire flag.
- Silenced a debug message which appeared every time a player right-clicked a block.
- Updated constants for `LevelSoundEventPacket`.
# 3.9.2
- Logger warnings for illegal player movements have been lowered to debug.
- TNT explosions now start from the center instead of the base. This fixes unexpected results when TNT is lit on top of obsidian.
- Fixed the `loadbefore` directive in `plugin.yml` sometimes being ignored.
- Fixed `Item->setCustomName()` with an empty string leaving behind an empty tag.
- Fixed incorrect positioning of bucket empty sound.
- Fixed some incorrect tag parsing in `/give` involving quoted numbers.

View File

@ -17,17 +17,17 @@
"ext-openssl": "*", "ext-openssl": "*",
"ext-pcre": "*", "ext-pcre": "*",
"ext-phar": "*", "ext-phar": "*",
"ext-pthreads": ">=3.1.7dev", "ext-pthreads": "~3.2.0",
"ext-reflection": "*", "ext-reflection": "*",
"ext-sockets": "*", "ext-sockets": "*",
"ext-spl": "*", "ext-spl": "*",
"ext-yaml": ">=2.0.0", "ext-yaml": ">=2.0.0",
"ext-zip": "*", "ext-zip": "*",
"ext-zlib": ">=1.2.11", "ext-zlib": ">=1.2.11",
"pocketmine/raklib": "^0.12.0", "pocketmine/raklib": "^0.12.5",
"pocketmine/spl": "^0.3.0", "pocketmine/spl": "^0.3.0",
"pocketmine/binaryutils": "^0.1.0", "pocketmine/binaryutils": "^0.1.9",
"pocketmine/nbt": "^0.2.6", "pocketmine/nbt": "^0.2.10",
"pocketmine/math": "^0.2.0", "pocketmine/math": "^0.2.0",
"pocketmine/snooze": "^0.1.0", "pocketmine/snooze": "^0.1.0",
"daverandom/callback-validator": "dev-master", "daverandom/callback-validator": "dev-master",

49
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "2f5313e4ebd7b62c785cf683b27464b4", "content-hash": "377d9e0ab5f1a9a4ef9b664706d26f5b",
"packages": [ "packages": [
{ {
"name": "adhocore/json-comment", "name": "adhocore/json-comment",
@ -92,16 +92,16 @@
}, },
{ {
"name": "pocketmine/binaryutils", "name": "pocketmine/binaryutils",
"version": "0.1.8", "version": "0.1.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/BinaryUtils.git", "url": "https://github.com/pmmp/BinaryUtils.git",
"reference": "33f511715d22418c03368b49b45a6c25d6b33806" "reference": "8b3b1160679398387cb896fd5d06018413437dfa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/33f511715d22418c03368b49b45a6c25d6b33806", "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8b3b1160679398387cb896fd5d06018413437dfa",
"reference": "33f511715d22418c03368b49b45a6c25d6b33806", "reference": "8b3b1160679398387cb896fd5d06018413437dfa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -119,10 +119,10 @@
], ],
"description": "Classes and methods for conveniently handling binary data", "description": "Classes and methods for conveniently handling binary data",
"support": { "support": {
"source": "https://github.com/pmmp/BinaryUtils/tree/0.1.8", "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.9",
"issues": "https://github.com/pmmp/BinaryUtils/issues" "issues": "https://github.com/pmmp/BinaryUtils/issues"
}, },
"time": "2019-01-16T17:31:44+00:00" "time": "2019-07-22T13:15:53+00:00"
}, },
{ {
"name": "pocketmine/math", "name": "pocketmine/math",
@ -160,23 +160,23 @@
}, },
{ {
"name": "pocketmine/nbt", "name": "pocketmine/nbt",
"version": "0.2.7", "version": "0.2.10",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/NBT.git", "url": "https://github.com/pmmp/NBT.git",
"reference": "2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a" "reference": "2db27aebe7dc89772aaa8df53361eef801f60063"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/NBT/zipball/2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a", "url": "https://api.github.com/repos/pmmp/NBT/zipball/2db27aebe7dc89772aaa8df53361eef801f60063",
"reference": "2f176c9f2fd9b31db8bc2ada2f38990157ec8f1a", "reference": "2db27aebe7dc89772aaa8df53361eef801f60063",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-zlib": "*", "ext-zlib": "*",
"php": ">=7.2.0", "php": ">=7.2.0",
"php-64bit": "*", "php-64bit": "*",
"pocketmine/binaryutils": "^0.1.0" "pocketmine/binaryutils": "^0.1.9"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -194,33 +194,33 @@
], ],
"description": "PHP library for working with Named Binary Tags", "description": "PHP library for working with Named Binary Tags",
"support": { "support": {
"source": "https://github.com/pmmp/NBT/tree/0.2.7", "source": "https://github.com/pmmp/NBT/tree/0.2.10",
"issues": "https://github.com/pmmp/NBT/issues" "issues": "https://github.com/pmmp/NBT/issues"
}, },
"time": "2019-03-29T19:39:42+00:00" "time": "2019-07-22T15:22:23+00:00"
}, },
{ {
"name": "pocketmine/raklib", "name": "pocketmine/raklib",
"version": "0.12.4", "version": "0.12.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pmmp/RakLib.git", "url": "https://github.com/pmmp/RakLib.git",
"reference": "fc1ccc8e61b9033e5372436b2e28a7a95388373f" "reference": "874db2d3c24117db2221c1e4550380478aeea852"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/fc1ccc8e61b9033e5372436b2e28a7a95388373f", "url": "https://api.github.com/repos/pmmp/RakLib/zipball/874db2d3c24117db2221c1e4550380478aeea852",
"reference": "fc1ccc8e61b9033e5372436b2e28a7a95388373f", "reference": "874db2d3c24117db2221c1e4550380478aeea852",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-bcmath": "*", "ext-bcmath": "*",
"ext-pthreads": ">=3.1.7dev", "ext-pthreads": "~3.2.0",
"ext-sockets": "*", "ext-sockets": "*",
"php": ">=7.2.0", "php": ">=7.2.0",
"php-64bit": "*", "php-64bit": "*",
"php-ipv6": "*", "php-ipv6": "*",
"pocketmine/binaryutils": "^0.1.0", "pocketmine/binaryutils": "^0.1.9",
"pocketmine/snooze": "^0.1.0", "pocketmine/snooze": "^0.1.0",
"pocketmine/spl": "^0.3.0" "pocketmine/spl": "^0.3.0"
}, },
@ -235,10 +235,10 @@
], ],
"description": "A RakNet server implementation written in PHP", "description": "A RakNet server implementation written in PHP",
"support": { "support": {
"source": "https://github.com/pmmp/RakLib/tree/0.12.4", "source": "https://github.com/pmmp/RakLib/tree/0.12",
"issues": "https://github.com/pmmp/RakLib/issues" "issues": "https://github.com/pmmp/RakLib/issues"
}, },
"time": "2019-05-02T14:53:51+00:00" "time": "2019-07-22T14:38:20+00:00"
}, },
{ {
"name": "pocketmine/snooze", "name": "pocketmine/snooze",
@ -302,7 +302,7 @@
], ],
"description": "Standard library files required by PocketMine-MP and related projects", "description": "Standard library files required by PocketMine-MP and related projects",
"support": { "support": {
"source": "https://github.com/pmmp/SPL/tree/0.3.2" "source": "https://github.com/pmmp/SPL/tree/master"
}, },
"time": "2018-08-12T15:17:39+00:00" "time": "2018-08-12T15:17:39+00:00"
} }
@ -311,7 +311,6 @@
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": {
"ext-pthreads": 20,
"daverandom/callback-validator": 20 "daverandom/callback-validator": 20
}, },
"prefer-stable": false, "prefer-stable": false,
@ -329,7 +328,7 @@
"ext-openssl": "*", "ext-openssl": "*",
"ext-pcre": "*", "ext-pcre": "*",
"ext-phar": "*", "ext-phar": "*",
"ext-pthreads": ">=3.1.7dev", "ext-pthreads": "~3.2.0",
"ext-reflection": "*", "ext-reflection": "*",
"ext-sockets": "*", "ext-sockets": "*",
"ext-spl": "*", "ext-spl": "*",

View File

@ -530,7 +530,7 @@ HIDE_FRIEND_COMPOUNDS = NO
# blocks will be appended to the function's detailed documentation block. # blocks will be appended to the function's detailed documentation block.
# The default value is: NO. # The default value is: NO.
HIDE_IN_BODY_DOCS = NO HIDE_IN_BODY_DOCS = YES
# The INTERNAL_DOCS tag determines if documentation that is typed after a # The INTERNAL_DOCS tag determines if documentation that is typed after a
# \internal command is included. If the tag is set to NO then the documentation # \internal command is included. If the tag is set to NO then the documentation
@ -600,7 +600,7 @@ SORT_MEMBER_DOCS = YES
# this will also influence the order of the classes in the class list. # this will also influence the order of the classes in the class list.
# The default value is: NO. # The default value is: NO.
SORT_BRIEF_DOCS = NO SORT_BRIEF_DOCS = YES
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and # (brief and detailed) documentation of class members so that constructors and
@ -612,7 +612,7 @@ SORT_BRIEF_DOCS = NO
# detailed member documentation. # detailed member documentation.
# The default value is: NO. # The default value is: NO.
SORT_MEMBERS_CTORS_1ST = NO SORT_MEMBERS_CTORS_1ST = YES
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will # of group names into alphabetical order. If set to NO the group names will

View File

@ -99,20 +99,20 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\network\mcpe\PlayerNetworkSessionAdapter; use pocketmine\network\mcpe\PlayerNetworkSessionAdapter;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\AvailableEntityIdentifiersPacket;
use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BatchPacket;
use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\BookEditPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
@ -211,7 +211,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
public const VIEW = Player::SPECTATOR; public const VIEW = Player::SPECTATOR;
/** /**
* Checks a supplied username and checks it is valid. * Validates the given username.
* *
* @param string $name * @param string $name
* *
@ -800,7 +800,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
} }
/** /**
* Gets the "friendly" name to display of this player to use in the chat. * Returns the "friendly" display name of this player to use in the chat.
* *
* @return string * @return string
*/ */
@ -1596,7 +1596,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* If you must tamper with this code, be aware that this can cause very nasty results. Do not waste our time * If you must tamper with this code, be aware that this can cause very nasty results. Do not waste our time
* asking for help if you suffer the consequences of messing with this. * asking for help if you suffer the consequences of messing with this.
*/ */
$this->server->getLogger()->warning($this->getName() . " moved too fast, reverting movement"); $this->server->getLogger()->debug($this->getName() . " moved too fast, reverting movement");
$this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); $this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition);
$revert = true; $revert = true;
}elseif(!$this->level->isInLoadedTerrain($newPos) or !$this->level->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ }elseif(!$this->level->isInLoadedTerrain($newPos) or !$this->level->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){
@ -1621,7 +1621,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$revert = true; $revert = true;
$this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()])); $this->server->getLogger()->debug($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()]));
$this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); $this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition);
} }
} }
@ -2157,7 +2157,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$pk->worldName = $this->server->getMotd(); $pk->worldName = $this->server->getMotd();
$this->dataPacket($pk); $this->dataPacket($pk);
$this->sendDataPacket(new AvailableEntityIdentifiersPacket()); $this->sendDataPacket(new AvailableActorIdentifiersPacket());
$this->sendDataPacket(new BiomeDefinitionListPacket()); $this->sendDataPacket(new BiomeDefinitionListPacket());
$this->level->sendTime($this); $this->level->sendTime($this);
@ -2279,14 +2279,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return true; return true;
} }
public function handleEntityEvent(EntityEventPacket $packet) : bool{ public function handleEntityEvent(ActorEventPacket $packet) : bool{
if(!$this->spawned or !$this->isAlive()){ if(!$this->spawned or !$this->isAlive()){
return true; return true;
} }
$this->doCloseInventory(); $this->doCloseInventory();
switch($packet->event){ switch($packet->event){
case EntityEventPacket::EATING_ITEM: case ActorEventPacket::EATING_ITEM:
if($packet->data === 0){ if($packet->data === 0){
return false; return false;
} }
@ -2855,6 +2855,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
case PlayerActionPacket::ACTION_STOP_SWIMMING: case PlayerActionPacket::ACTION_STOP_SWIMMING:
//TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!) //TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!)
break; break;
case PlayerActionPacket::ACTION_INTERACT_BLOCK: //ignored (for now)
break;
default: default:
$this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName()); $this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName());
return false; return false;
@ -2981,7 +2983,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return $handled; return $handled;
} }
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ public function handleBlockEntityData(BlockActorDataPacket $packet) : bool{
if(!$this->spawned or !$this->isAlive()){ if(!$this->spawned or !$this->isAlive()){
return true; return true;
} }
@ -3382,7 +3384,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
$pk->needsTranslation = true; $pk->needsTranslation = true;
$pk->message = $this->server->getLanguage()->translateString($message, $parameters, "pocketmine."); $pk->message = $this->server->getLanguage()->translateString($message, $parameters, "pocketmine.");
foreach($parameters as $i => $p){ foreach($parameters as $i => $p){
$parameters[$i] = $this->server->getLanguage()->translateString($p, $parameters, "pocketmine."); $parameters[$i] = $this->server->getLanguage()->translateString($p, [], "pocketmine.");
} }
$pk->parameters = $parameters; $pk->parameters = $parameters;
}else{ }else{

View File

@ -102,8 +102,8 @@ namespace pocketmine {
if(substr_count($pthreads_version, ".") < 2){ if(substr_count($pthreads_version, ".") < 2){
$pthreads_version = "0.$pthreads_version"; $pthreads_version = "0.$pthreads_version";
} }
if(version_compare($pthreads_version, "3.1.7dev") < 0){ if(version_compare($pthreads_version, "3.2.0") < 0){
$messages[] = "pthreads >= 3.1.7dev is required, while you have $pthreads_version."; $messages[] = "pthreads >= 3.2.0 is required, while you have $pthreads_version.";
} }
} }

View File

@ -22,6 +22,6 @@
namespace pocketmine; namespace pocketmine;
const NAME = "PocketMine-MP"; const NAME = "PocketMine-MP";
const BASE_VERSION = "3.8.5"; const BASE_VERSION = "3.9.2";
const IS_DEVELOPMENT_BUILD = false; const IS_DEVELOPMENT_BUILD = false;
const BUILD_NUMBER = 0; const BUILD_NUMBER = 0;

View File

@ -32,6 +32,7 @@ use pocketmine\level\sound\FizzSound;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use function array_fill; use function array_fill;
use function intdiv;
use function lcg_value; use function lcg_value;
use function min; use function min;
@ -372,7 +373,7 @@ abstract class Liquid extends Transparent{
*/ */
private function getOptimalFlowDirections() : array{ private function getOptimalFlowDirections() : array{
$flowCost = array_fill(0, 4, 1000); $flowCost = array_fill(0, 4, 1000);
$maxCost = 4 / $this->getFlowDecayPerBlock(); $maxCost = intdiv(4, $this->getFlowDecayPerBlock());
for($j = 0; $j < 4; ++$j){ for($j = 0; $j < 4; ++$j){
$x = $this->x; $x = $this->x;
$y = $this->y; $y = $this->y;

View File

@ -74,14 +74,14 @@ class FormattedCommandAlias extends Command{
$index = strpos($formatString, '$'); $index = strpos($formatString, '$');
while($index !== false){ while($index !== false){
$start = $index; $start = $index;
if($index > 0 and $formatString{$start - 1} === "\\"){ if($index > 0 and $formatString[$start - 1] === "\\"){
$formatString = substr($formatString, 0, $start - 1) . substr($formatString, $start); $formatString = substr($formatString, 0, $start - 1) . substr($formatString, $start);
$index = strpos($formatString, '$', $index); $index = strpos($formatString, '$', $index);
continue; continue;
} }
$required = false; $required = false;
if($formatString{$index + 1} == '$'){ if($formatString[$index + 1] == '$'){
$required = true; $required = true;
++$index; ++$index;
@ -91,7 +91,7 @@ class FormattedCommandAlias extends Command{
$argStart = $index; $argStart = $index;
while($index < strlen($formatString) and self::inRange(ord($formatString{$index}) - 48, 0, 9)){ while($index < strlen($formatString) and self::inRange(ord($formatString[$index]) - 48, 0, 9)){
++$index; ++$index;
} }
@ -109,7 +109,7 @@ class FormattedCommandAlias extends Command{
$rest = false; $rest = false;
if($index < strlen($formatString) and $formatString{$index} === "-"){ if($index < strlen($formatString) and $formatString[$index] === "-"){
$rest = true; $rest = true;
++$index; ++$index;
} }

View File

@ -65,7 +65,7 @@ abstract class VanillaCommand extends Command{
* @return float * @return float
*/ */
protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{
if($input{0} === "~"){ if($input[0] === "~"){
$value = $this->getDouble($sender, substr($input, 1)); $value = $this->getDouble($sender, substr($input, 1));
return $original + $value; return $original + $value;

View File

@ -62,12 +62,12 @@ use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\SetEntityDataPacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket;
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
use pocketmine\Server; use pocketmine\Server;
@ -154,70 +154,76 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public const DATA_LEAD_HOLDER_EID = 37; //long public const DATA_LEAD_HOLDER_EID = 37; //long
public const DATA_SCALE = 38; //float public const DATA_SCALE = 38; //float
public const DATA_HAS_NPC_COMPONENT = 39; //byte (???) public const DATA_HAS_NPC_COMPONENT = 39; //byte (???)
public const DATA_SKIN_ID = 40; //string public const DATA_NPC_SKIN_INDEX = 40; //string
public const DATA_NPC_SKIN_ID = 41; //string public const DATA_NPC_ACTIONS = 41; //string (maybe JSON blob?)
public const DATA_URL_TAG = 42; //string public const DATA_MAX_AIR = 42; //short
public const DATA_MAX_AIR = 43; //short public const DATA_MARK_VARIANT = 43; //int
public const DATA_MARK_VARIANT = 44; //int public const DATA_CONTAINER_TYPE = 44; //byte (ContainerComponent)
public const DATA_CONTAINER_TYPE = 45; //byte (ContainerComponent) public const DATA_CONTAINER_BASE_SIZE = 45; //int (ContainerComponent)
public const DATA_CONTAINER_BASE_SIZE = 46; //int (ContainerComponent) public const DATA_CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 46; //int (used for llamas, inventory size is baseSize + thisProp * strength)
public const DATA_CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 47; //int (used for llamas, inventory size is baseSize + thisProp * strength) public const DATA_BLOCK_TARGET = 47; //block coords (ender crystal)
public const DATA_BLOCK_TARGET = 48; //block coords (ender crystal) public const DATA_WITHER_INVULNERABLE_TICKS = 48; //int
public const DATA_WITHER_INVULNERABLE_TICKS = 49; //int public const DATA_WITHER_TARGET_1 = 49; //long
public const DATA_WITHER_TARGET_1 = 50; //long public const DATA_WITHER_TARGET_2 = 50; //long
public const DATA_WITHER_TARGET_2 = 51; //long public const DATA_WITHER_TARGET_3 = 51; //long
public const DATA_WITHER_TARGET_3 = 52; //long /* 52 (short) */
/* 53 (short) */ public const DATA_BOUNDING_BOX_WIDTH = 53; //float
public const DATA_BOUNDING_BOX_WIDTH = 54; //float public const DATA_BOUNDING_BOX_HEIGHT = 54; //float
public const DATA_BOUNDING_BOX_HEIGHT = 55; //float public const DATA_FUSE_LENGTH = 55; //int
public const DATA_FUSE_LENGTH = 56; //int public const DATA_RIDER_SEAT_POSITION = 56; //vector3f
public const DATA_RIDER_SEAT_POSITION = 57; //vector3f public const DATA_RIDER_ROTATION_LOCKED = 57; //byte
public const DATA_RIDER_ROTATION_LOCKED = 58; //byte public const DATA_RIDER_MAX_ROTATION = 58; //float
public const DATA_RIDER_MAX_ROTATION = 59; //float public const DATA_RIDER_MIN_ROTATION = 59; //float
public const DATA_RIDER_MIN_ROTATION = 60; //float public const DATA_AREA_EFFECT_CLOUD_RADIUS = 60; //float
public const DATA_AREA_EFFECT_CLOUD_RADIUS = 61; //float public const DATA_AREA_EFFECT_CLOUD_WAITING = 61; //int
public const DATA_AREA_EFFECT_CLOUD_WAITING = 62; //int public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 62; //int
public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int /* 63 (int) shulker-related */
/* 64 (int) shulker-related */ public const DATA_SHULKER_ATTACH_FACE = 64; //byte
public const DATA_SHULKER_ATTACH_FACE = 65; //byte /* 65 (short) shulker-related */
/* 66 (short) shulker-related */ public const DATA_SHULKER_ATTACH_POS = 66; //block coords
public const DATA_SHULKER_ATTACH_POS = 67; //block coords public const DATA_TRADING_PLAYER_EID = 67; //long
public const DATA_TRADING_PLAYER_EID = 68; //long
/* 70 (byte) command-block */ /* 69 (byte) command-block */
public const DATA_COMMAND_BLOCK_COMMAND = 71; //string public const DATA_COMMAND_BLOCK_COMMAND = 70; //string
public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 72; //string public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 71; //string
public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 72; //byte
public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 73; //byte
public const DATA_STRENGTH = 75; //int public const DATA_STRENGTH = 74; //int
public const DATA_MAX_STRENGTH = 76; //int public const DATA_MAX_STRENGTH = 75; //int
/* 77 (int) */ /* 76 (int) */
public const DATA_LIMITED_LIFE = 78; public const DATA_LIMITED_LIFE = 77;
public const DATA_ARMOR_STAND_POSE_INDEX = 79; //int public const DATA_ARMOR_STAND_POSE_INDEX = 78; //int
public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 80; //int public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 79; //int
public const DATA_ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always public const DATA_ALWAYS_SHOW_NAMETAG = 80; //byte: -1 = default, 0 = only when looked at, 1 = always
public const DATA_COLOR_2 = 82; //byte public const DATA_COLOR_2 = 81; //byte
/* 83 (unknown) */ /* 82 (unknown) */
public const DATA_SCORE_TAG = 84; //string public const DATA_SCORE_TAG = 83; //string
public const DATA_BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner public const DATA_BALLOON_ATTACHED_ENTITY = 84; //int64, entity unique ID of owner
public const DATA_PUFFERFISH_SIZE = 86; //byte public const DATA_PUFFERFISH_SIZE = 85; //byte
public const DATA_BOAT_BUBBLE_TIME = 87; //int (time in bubble column) public const DATA_BOAT_BUBBLE_TIME = 86; //int (time in bubble column)
public const DATA_PLAYER_AGENT_EID = 88; //long public const DATA_PLAYER_AGENT_EID = 87; //long
/* 89 (float) related to panda sitting /* 88 (float) related to panda sitting
* 90 (float) related to panda sitting */ * 89 (float) related to panda sitting */
public const DATA_EAT_COUNTER = 91; //int (used by pandas) public const DATA_EAT_COUNTER = 90; //int (used by pandas)
public const DATA_FLAGS2 = 92; //long (extended data flags) public const DATA_FLAGS2 = 91; //long (extended data flags)
/* 93 (float) related to panda lying down /* 92 (float) related to panda lying down
* 94 (float) related to panda lying down */ * 93 (float) related to panda lying down */
public const DATA_AREA_EFFECT_CLOUD_DURATION = 95; //int public const DATA_AREA_EFFECT_CLOUD_DURATION = 94; //int
public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 95; //int
public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 96; //float, usually negative
public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 97; //float
public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 98; //int
public const DATA_INTERACTIVE_TAG = 100; //string (button text) public const DATA_INTERACTIVE_TAG = 99; //string (button text)
public const DATA_TRADE_TIER = 101; //int public const DATA_TRADE_TIER = 100; //int
public const DATA_MAX_TRADE_TIER = 102; //int public const DATA_MAX_TRADE_TIER = 101; //int
public const DATA_TRADE_XP = 103; //int public const DATA_TRADE_XP = 102; //int
public const DATA_SKIN_ID = 103; //int ???
/* 104 (int) related to wither */
public const DATA_COMMAND_BLOCK_TICK_DELAY = 105; //int
public const DATA_COMMAND_BLOCK_EXECUTE_ON_FIRST_TICK = 106; //byte
public const DATA_AMBIENT_SOUND_INTERVAL_MIN = 107; //float
public const DATA_AMBIENT_SOUND_INTERVAL_RANGE = 108; //float
public const DATA_AMBIENT_SOUND_EVENT = 109; //string
public const DATA_FLAG_ONFIRE = 0; public const DATA_FLAG_ONFIRE = 0;
public const DATA_FLAG_SNEAKING = 1; public const DATA_FLAG_SNEAKING = 1;
@ -662,7 +668,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @return bool * @return bool
*/ */
public function isNameTagAlwaysVisible() : bool{ public function isNameTagAlwaysVisible() : bool{
return $this->getGenericFlag(self::DATA_FLAG_ALWAYS_SHOW_NAMETAG); return $this->propertyManager->getByte(self::DATA_ALWAYS_SHOW_NAMETAG) === 1;
} }
@ -1137,7 +1143,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->setFireTicks($ticks); $this->setFireTicks($ticks);
} }
$this->setGenericFlag(self::DATA_FLAG_ONFIRE, true); $this->setGenericFlag(self::DATA_FLAG_ONFIRE, $this->isOnFire());
} }
/** /**
@ -1235,7 +1241,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
protected function broadcastMovement(bool $teleport = false) : void{ protected function broadcastMovement(bool $teleport = false) : void{
$pk = new MoveEntityAbsolutePacket(); $pk = new MoveActorAbsolutePacket();
$pk->entityRuntimeId = $this->id; $pk->entityRuntimeId = $this->id;
$pk->position = $this->getOffsetPosition($this); $pk->position = $this->getOffsetPosition($this);
@ -1247,14 +1253,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$pk->zRot = $this->yaw; $pk->zRot = $this->yaw;
if($teleport){ if($teleport){
$pk->flags |= MoveEntityAbsolutePacket::FLAG_TELEPORT; $pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT;
} }
$this->level->broadcastPacketToViewers($this, $pk); $this->level->broadcastPacketToViewers($this, $pk);
} }
protected function broadcastMotion() : void{ protected function broadcastMotion() : void{
$pk = new SetEntityMotionPacket(); $pk = new SetActorMotionPacket();
$pk->entityRuntimeId = $this->id; $pk->entityRuntimeId = $this->id;
$pk->motion = $this->getMotion(); $pk->motion = $this->getMotion();
@ -2021,7 +2027,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
* @param Player $player * @param Player $player
*/ */
protected function sendSpawnPacket(Player $player) : void{ protected function sendSpawnPacket(Player $player) : void{
$pk = new AddEntityPacket(); $pk = new AddActorPacket();
$pk->entityRuntimeId = $this->getId(); $pk->entityRuntimeId = $this->getId();
$pk->type = static::NETWORK_ID; $pk->type = static::NETWORK_ID;
$pk->position = $this->asVector3(); $pk->position = $this->asVector3();
@ -2071,7 +2077,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public function despawnFrom(Player $player, bool $send = true) : void{ public function despawnFrom(Player $player, bool $send = true) : void{
if(isset($this->hasSpawned[$player->getLoaderId()])){ if(isset($this->hasSpawned[$player->getLoaderId()])){
if($send){ if($send){
$pk = new RemoveEntityPacket(); $pk = new RemoveActorPacket();
$pk->entityUniqueId = $this->id; $pk->entityUniqueId = $this->id;
$player->dataPacket($pk); $player->dataPacket($pk);
} }
@ -2193,7 +2199,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$player = [$player]; $player = [$player];
} }
$pk = new SetEntityDataPacket(); $pk = new SetActorDataPacket();
$pk->entityRuntimeId = $this->getId(); $pk->entityRuntimeId = $this->getId();
$pk->metadata = $data ?? $this->propertyManager->getAll(); $pk->metadata = $data ?? $this->propertyManager->getAll();
@ -2210,7 +2216,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{
$pk = new EntityEventPacket(); $pk = new ActorEventPacket();
$pk->entityRuntimeId = $this->id; $pk->entityRuntimeId = $this->id;
$pk->event = $eventId; $pk->event = $eventId;
$pk->data = $eventData ?? 0; $pk->data = $eventData ?? 0;

View File

@ -46,8 +46,8 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket;
@ -628,7 +628,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
//Old hotbar saving stuff, ignore it //Old hotbar saving stuff, ignore it
}elseif($slot >= 100 and $slot < 104){ //Armor }elseif($slot >= 100 and $slot < 104){ //Armor
$this->armorInventory->setItem($slot - 100, Item::nbtDeserialize($item)); $this->armorInventory->setItem($slot - 100, Item::nbtDeserialize($item));
}else{ }elseif($slot >= 9 and $slot < $this->inventory->getSize() + 9){
$this->inventory->setItem($slot - 9, Item::nbtDeserialize($item)); $this->inventory->setItem($slot - 9, Item::nbtDeserialize($item));
} }
} }
@ -754,7 +754,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$this->addEffect(new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 40 * 20, 1)); $this->addEffect(new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 40 * 20, 1));
$this->addEffect(new EffectInstance(Effect::getEffect(Effect::ABSORPTION), 5 * 20, 1)); $this->addEffect(new EffectInstance(Effect::getEffect(Effect::ABSORPTION), 5 * 20, 1));
$this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); $this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM);
$this->level->broadcastLevelEvent($this->add(0, $this->eyeHeight, 0), LevelEventPacket::EVENT_SOUND_TOTEM); $this->level->broadcastLevelEvent($this->add(0, $this->eyeHeight, 0), LevelEventPacket::EVENT_SOUND_TOTEM);
$hand = $this->inventory->getItemInHand(); $hand = $this->inventory->getItemInHand();

View File

@ -44,7 +44,7 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket;
use pocketmine\Player; use pocketmine\Player;
@ -143,7 +143,7 @@ abstract class Living extends Entity implements Damageable{
parent::setHealth($amount); parent::setHealth($amount);
$this->attributeMap->getAttribute(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); $this->attributeMap->getAttribute(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true);
if($this->isAlive() and !$wasAlive){ if($this->isAlive() and !$wasAlive){
$this->broadcastEntityEvent(EntityEventPacket::RESPAWN); $this->broadcastEntityEvent(ActorEventPacket::RESPAWN);
} }
} }
@ -541,7 +541,9 @@ abstract class Living extends Entity implements Damageable{
} }
public function attack(EntityDamageEvent $source) : void{ public function attack(EntityDamageEvent $source) : void{
if($this->attackTime > 0 or $this->noDamageTicks > 0){ if($this->noDamageTicks > 0){
$source->setCancelled();
}elseif($this->attackTime > 0){
$lastCause = $this->getLastDamageCause(); $lastCause = $this->getLastDamageCause();
if($lastCause !== null and $lastCause->getBaseDamage() >= $source->getBaseDamage()){ if($lastCause !== null and $lastCause->getBaseDamage() >= $source->getBaseDamage()){
$source->setCancelled(); $source->setCancelled();
@ -604,7 +606,7 @@ abstract class Living extends Entity implements Damageable{
} }
protected function doHitAnimation() : void{ protected function doHitAnimation() : void{
$this->broadcastEntityEvent(EntityEventPacket::HURT_ANIMATION); $this->broadcastEntityEvent(ActorEventPacket::HURT_ANIMATION);
} }
public function knockBack(Entity $attacker, float $damage, float $x, float $z, float $base = 0.4) : void{ public function knockBack(Entity $attacker, float $damage, float $x, float $z, float $base = 0.4) : void{
@ -662,7 +664,7 @@ abstract class Living extends Entity implements Damageable{
} }
protected function startDeathAnimation() : void{ protected function startDeathAnimation() : void{
$this->broadcastEntityEvent(EntityEventPacket::DEATH_ANIMATION); $this->broadcastEntityEvent(ActorEventPacket::DEATH_ANIMATION);
} }
protected function endDeathAnimation() : void{ protected function endDeathAnimation() : void{

View File

@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ActorEventPacket;
use function atan2; use function atan2;
use function mt_rand; use function mt_rand;
use function sqrt; use function sqrt;
@ -68,7 +68,7 @@ class Squid extends WaterAnimal{
$this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize(); $this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize();
} }
$this->broadcastEntityEvent(EntityEventPacket::SQUID_INK_CLOUD); $this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD);
} }
} }

View File

@ -28,8 +28,8 @@ use pocketmine\event\entity\ItemDespawnEvent;
use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\entity\ItemSpawnEvent;
use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\event\inventory\InventoryPickupItemEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\Player; use pocketmine\Player;
use function get_class; use function get_class;
@ -192,7 +192,7 @@ class ItemEntity extends Entity{
} }
protected function sendSpawnPacket(Player $player) : void{ protected function sendSpawnPacket(Player $player) : void{
$pk = new AddItemEntityPacket(); $pk = new AddItemActorPacket();
$pk->entityRuntimeId = $this->getId(); $pk->entityRuntimeId = $this->getId();
$pk->position = $this->asVector3(); $pk->position = $this->asVector3();
$pk->motion = $this->getMotion(); $pk->motion = $this->getMotion();
@ -229,7 +229,7 @@ class ItemEntity extends Entity{
break; break;
} }
$pk = new TakeItemEntityPacket(); $pk = new TakeItemActorPacket();
$pk->eid = $player->getId(); $pk->eid = $player->getId();
$pk->target = $this->getId(); $pk->target = $this->getId();
$this->server->broadcastPacket($this->getViewers(), $pk); $this->server->broadcastPacket($this->getViewers(), $pk);

View File

@ -152,9 +152,11 @@ class Painting extends Entity{
protected function sendSpawnPacket(Player $player) : void{ protected function sendSpawnPacket(Player $player) : void{
$pk = new AddPaintingPacket(); $pk = new AddPaintingPacket();
$pk->entityRuntimeId = $this->getId(); $pk->entityRuntimeId = $this->getId();
$pk->x = $this->blockIn->x; $pk->position = new Vector3(
$pk->y = $this->blockIn->y; ($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
$pk->z = $this->blockIn->z; ($this->boundingBox->minY + $this->boundingBox->maxY) / 2,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
);
$pk->direction = $this->direction; $pk->direction = $this->direction;
$pk->title = $this->motive; $pk->title = $this->motive;

View File

@ -28,6 +28,7 @@ use pocketmine\entity\Explosive;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\event\entity\ExplosionPrimeEvent;
use pocketmine\level\Explosion; use pocketmine\level\Explosion;
use pocketmine\level\Position;
use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\ShortTag;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
@ -105,7 +106,7 @@ class PrimedTNT extends Entity implements Explosive{
$ev = new ExplosionPrimeEvent($this, 4); $ev = new ExplosionPrimeEvent($this, 4);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$explosion = new Explosion($this, $ev->getForce(), $this); $explosion = new Explosion(Position::fromObject($this->add(0, $this->height / 2, 0), $this->level), $ev->getForce(), $this);
if($ev->isBlockBreaking()){ if($ev->isBlockBreaking()){
$explosion->explodeA(); $explosion->explodeA();
} }

View File

@ -32,9 +32,9 @@ use pocketmine\item\ItemFactory;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\RayTraceResult; use pocketmine\math\RayTraceResult;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\Player; use pocketmine\Player;
use function mt_rand; use function mt_rand;
use function sqrt; use function sqrt;
@ -143,7 +143,7 @@ class Arrow extends Projectile{
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
parent::onHitBlock($blockHit, $hitResult); parent::onHitBlock($blockHit, $hitResult);
$this->broadcastEntityEvent(EntityEventPacket::ARROW_SHAKE, 7); //7 ticks $this->broadcastEntityEvent(ActorEventPacket::ARROW_SHAKE, 7); //7 ticks
} }
protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{ protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{
@ -193,7 +193,7 @@ class Arrow extends Projectile{
return; return;
} }
$pk = new TakeItemEntityPacket(); $pk = new TakeItemActorPacket();
$pk->eid = $player->getId(); $pk->eid = $player->getId();
$pk->target = $this->getId(); $pk->target = $this->getId();
$this->server->broadcastPacket($this->getViewers(), $pk); $this->server->broadcastPacket($this->getViewers(), $pk);

View File

@ -79,8 +79,8 @@ class ShapedRecipe implements CraftingRecipe{
} }
for($x = 0; $x < $this->width; ++$x){ for($x = 0; $x < $this->width; ++$x){
if($row{$x} !== ' ' and !isset($ingredients[$row{$x}])){ if($row[$x] !== ' ' and !isset($ingredients[$row[$x]])){
throw new \InvalidArgumentException("No item specified for symbol '" . $row{$x} . "'"); throw new \InvalidArgumentException("No item specified for symbol '" . $row[$x] . "'");
} }
} }
} }

View File

@ -85,7 +85,7 @@ class Bucket extends Item implements Consumable{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm(), true, true); $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm(), true, true);
$player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); $player->getLevel()->broadcastLevelSoundEvent($blockReplace->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound());
if($player->isSurvival()){ if($player->isSurvival()){
$player->getInventory()->setItemInHand($ev->getItem()); $player->getInventory()->setItemInHand($ev->getItem());

View File

@ -467,7 +467,7 @@ class Item implements ItemIds, \JsonSerializable{
*/ */
public function setCustomName(string $name) : Item{ public function setCustomName(string $name) : Item{
if($name === ""){ if($name === ""){
$this->clearCustomName(); return $this->clearCustomName();
} }
/** @var CompoundTag $display */ /** @var CompoundTag $display */

View File

@ -190,7 +190,7 @@ class BaseLang{
$len = strlen($text); $len = strlen($text);
for($i = 0; $i < $len; ++$i){ for($i = 0; $i < $len; ++$i){
$c = $text{$i}; $c = $text[$i];
if($replaceString !== null){ if($replaceString !== null){
$ord = ord($c); $ord = ord($c);
if( if(

View File

@ -72,7 +72,7 @@ use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BatchPacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
@ -564,7 +564,7 @@ class Level implements ChunkManager, Metadatable{
$pk = new LevelSoundEventPacket(); $pk = new LevelSoundEventPacket();
$pk->sound = $soundId; $pk->sound = $soundId;
$pk->extraData = $extraData; $pk->extraData = $extraData;
$pk->entityType = AddEntityPacket::LEGACY_ID_MAP_BC[$entityTypeId] ?? ":"; $pk->entityType = AddActorPacket::LEGACY_ID_MAP_BC[$entityTypeId] ?? ":";
$pk->isBabyMob = $isBabyMob; $pk->isBabyMob = $isBabyMob;
$pk->disableRelativeVolume = $disableRelativeVolume; $pk->disableRelativeVolume = $disableRelativeVolume;
$pk->position = $pos->asVector3(); $pk->position = $pos->asVector3();

View File

@ -460,7 +460,7 @@ class Chunk{
* @return int 0-255 * @return int 0-255
*/ */
public function getBiomeId(int $x, int $z) : int{ public function getBiomeId(int $x, int $z) : int{
return ord($this->biomeIds{($z << 4) | $x}); return ord($this->biomeIds[($z << 4) | $x]);
} }
/** /**
@ -472,7 +472,7 @@ class Chunk{
*/ */
public function setBiomeId(int $x, int $z, int $biomeId){ public function setBiomeId(int $x, int $z, int $biomeId){
$this->hasChanged = true; $this->hasChanged = true;
$this->biomeIds{($z << 4) | $x} = chr($biomeId & 0xff); $this->biomeIds[($z << 4) | $x] = chr($biomeId & 0xff);
} }
/** /**
@ -869,13 +869,10 @@ class Chunk{
public function networkSerialize() : string{ public function networkSerialize() : string{
$result = ""; $result = "";
$subChunkCount = $this->getSubChunkSendCount(); $subChunkCount = $this->getSubChunkSendCount();
$result .= chr($subChunkCount);
for($y = 0; $y < $subChunkCount; ++$y){ for($y = 0; $y < $subChunkCount; ++$y){
$result .= $this->subChunks[$y]->networkSerialize(); $result .= $this->subChunks[$y]->networkSerialize();
} }
$result .= pack("v*", ...$this->heightMap) $result .= $this->biomeIds . chr(0); //border block array count
. $this->biomeIds
. chr(0); //border block array count
//Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client.
foreach($this->tiles as $tile){ foreach($this->tiles as $tile){

View File

@ -71,31 +71,31 @@ class SubChunk implements SubChunkInterface{
} }
public function getBlockId(int $x, int $y, int $z) : int{ public function getBlockId(int $x, int $y, int $z) : int{
return ord($this->ids{($x << 8) | ($z << 4) | $y}); return ord($this->ids[($x << 8) | ($z << 4) | $y]);
} }
public function setBlockId(int $x, int $y, int $z, int $id) : bool{ public function setBlockId(int $x, int $y, int $z, int $id) : bool{
$this->ids{($x << 8) | ($z << 4) | $y} = chr($id); $this->ids[($x << 8) | ($z << 4) | $y] = chr($id);
return true; return true;
} }
public function getBlockData(int $x, int $y, int $z) : int{ public function getBlockData(int $x, int $y, int $z) : int{
return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; return (ord($this->data[($x << 7) | ($z << 3) | ($y >> 1)]) >> (($y & 1) << 2)) & 0xf;
} }
public function setBlockData(int $x, int $y, int $z, int $data) : bool{ public function setBlockData(int $x, int $y, int $z, int $data) : bool{
$i = ($x << 7) | ($z << 3) | ($y >> 1); $i = ($x << 7) | ($z << 3) | ($y >> 1);
$shift = ($y & 1) << 2; $shift = ($y & 1) << 2;
$byte = ord($this->data{$i}); $byte = ord($this->data[$i]);
$this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift)); $this->data[$i] = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift));
return true; return true;
} }
public function getFullBlock(int $x, int $y, int $z) : int{ public function getFullBlock(int $x, int $y, int $z) : int{
$i = ($x << 8) | ($z << 4) | $y; $i = ($x << 8) | ($z << 4) | $y;
return (ord($this->ids{$i}) << 4) | ((ord($this->data{$i >> 1}) >> (($y & 1) << 2)) & 0xf); return (ord($this->ids[$i]) << 4) | ((ord($this->data[$i >> 1]) >> (($y & 1) << 2)) & 0xf);
} }
public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{ public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{
@ -103,8 +103,8 @@ class SubChunk implements SubChunkInterface{
$changed = false; $changed = false;
if($id !== null){ if($id !== null){
$block = chr($id); $block = chr($id);
if($this->ids{$i} !== $block){ if($this->ids[$i] !== $block){
$this->ids{$i} = $block; $this->ids[$i] = $block;
$changed = true; $changed = true;
} }
} }
@ -113,10 +113,10 @@ class SubChunk implements SubChunkInterface{
$i >>= 1; $i >>= 1;
$shift = ($y & 1) << 2; $shift = ($y & 1) << 2;
$oldPair = ord($this->data{$i}); $oldPair = ord($this->data[$i]);
$newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift);
if($newPair !== $oldPair){ if($newPair !== $oldPair){
$this->data{$i} = chr($newPair); $this->data[$i] = chr($newPair);
$changed = true; $changed = true;
} }
} }
@ -125,29 +125,29 @@ class SubChunk implements SubChunkInterface{
} }
public function getBlockLight(int $x, int $y, int $z) : int{ public function getBlockLight(int $x, int $y, int $z) : int{
return (ord($this->blockLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; return (ord($this->blockLight[($x << 7) | ($z << 3) | ($y >> 1)]) >> (($y & 1) << 2)) & 0xf;
} }
public function setBlockLight(int $x, int $y, int $z, int $level) : bool{ public function setBlockLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) | ($z << 3) | ($y >> 1); $i = ($x << 7) | ($z << 3) | ($y >> 1);
$shift = ($y & 1) << 2; $shift = ($y & 1) << 2;
$byte = ord($this->blockLight{$i}); $byte = ord($this->blockLight[$i]);
$this->blockLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); $this->blockLight[$i] = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift));
return true; return true;
} }
public function getBlockSkyLight(int $x, int $y, int $z) : int{ public function getBlockSkyLight(int $x, int $y, int $z) : int{
return (ord($this->skyLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; return (ord($this->skyLight[($x << 7) | ($z << 3) | ($y >> 1)]) >> (($y & 1) << 2)) & 0xf;
} }
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{ public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) | ($z << 3) | ($y >> 1); $i = ($x << 7) | ($z << 3) | ($y >> 1);
$shift = ($y & 1) << 2; $shift = ($y & 1) << 2;
$byte = ord($this->skyLight{$i}); $byte = ord($this->skyLight[$i]);
$this->skyLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); $this->skyLight[$i] = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift));
return true; return true;
} }
@ -156,7 +156,7 @@ class SubChunk implements SubChunkInterface{
$low = ($x << 8) | ($z << 4); $low = ($x << 8) | ($z << 4);
$i = $low | 0x0f; $i = $low | 0x0f;
for(; $i >= $low; --$i){ for(; $i >= $low; --$i){
if($this->ids{$i} !== "\x00"){ if($this->ids[$i] !== "\x00"){
return $i & 0x0f; return $i & 0x0f;
} }
} }

View File

@ -26,7 +26,7 @@ namespace pocketmine\level\format\io;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BatchPacket;
use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\network\mcpe\protocol\LevelChunkPacket;
use pocketmine\scheduler\AsyncTask; use pocketmine\scheduler\AsyncTask;
use pocketmine\Server; use pocketmine\Server;
use function assert; use function assert;
@ -42,6 +42,9 @@ class ChunkRequestTask extends AsyncTask{
protected $compressionLevel; protected $compressionLevel;
/** @var int */
private $subChunkCount;
public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){ public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){
$this->levelId = $level->getId(); $this->levelId = $level->getId();
$this->compressionLevel = $level->getServer()->networkCompressionLevel; $this->compressionLevel = $level->getServer()->networkCompressionLevel;
@ -49,13 +52,11 @@ class ChunkRequestTask extends AsyncTask{
$this->chunk = $chunk->networkSerialize(); $this->chunk = $chunk->networkSerialize();
$this->chunkX = $chunkX; $this->chunkX = $chunkX;
$this->chunkZ = $chunkZ; $this->chunkZ = $chunkZ;
$this->subChunkCount = $chunk->getSubChunkSendCount();
} }
public function onRun(){ public function onRun(){
$pk = new FullChunkDataPacket(); $pk = LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $this->subChunkCount, $this->chunk);
$pk->chunkX = $this->chunkX;
$pk->chunkZ = $this->chunkZ;
$pk->data = $this->chunk;
$batch = new BatchPacket(); $batch = new BatchPacket();
$batch->addPacket($pk); $batch->addPacket($pk);

View File

@ -47,7 +47,7 @@ if(!extension_loaded('pocketmine_chunkutils')){
for($z = $x; $z < $zM; $z += 16){ for($z = $x; $z < $zM; $z += 16){
$yM = $z + 4096; $yM = $z + 4096;
for($y = $z; $y < $yM; $y += 256){ for($y = $z; $y < $yM; $y += 256){
$result{$i} = $array{$y}; $result[$i] = $array[$y];
++$i; ++$i;
} }
} }
@ -76,13 +76,13 @@ if(!extension_loaded('pocketmine_chunkutils')){
for($y = 0; $y < 8; ++$y){ for($y = 0; $y < 8; ++$y){
$j = (($y << 8) | $zx); $j = (($y << 8) | $zx);
$j80 = ($j | 0x80); $j80 = ($j | 0x80);
if($array{$j} === $commonValue and $array{$j80} === $commonValue){ if($array[$j] === $commonValue and $array[$j80] === $commonValue){
//values are already filled //values are already filled
}else{ }else{
$i1 = ord($array{$j}); $i1 = ord($array[$j]);
$i2 = ord($array{$j80}); $i2 = ord($array[$j80]);
$result{$i} = chr(($i2 << 4) | ($i1 & 0x0f)); $result[$i] = chr(($i2 << 4) | ($i1 & 0x0f));
$result{$i | 0x80} = chr(($i1 >> 4) | ($i2 & 0xf0)); $result[$i | 0x80] = chr(($i1 >> 4) | ($i2 & 0xf0));
} }
$i++; $i++;
} }
@ -104,7 +104,7 @@ if(!extension_loaded('pocketmine_chunkutils')){
public static function convertBiomeColors(array $array) : string{ public static function convertBiomeColors(array $array) : string{
$result = str_repeat("\x00", 256); $result = str_repeat("\x00", 256);
foreach($array as $i => $color){ foreach($array as $i => $color){
$result{$i} = chr(($color >> 24) & 0xff); $result[$i] = chr(($color >> 24) & 0xff);
} }
return $result; return $result;
} }

View File

@ -30,7 +30,7 @@ use pocketmine\level\ChunkManager;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\utils\Random; use pocketmine\utils\Random;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use function ctype_digit; use function preg_match;
abstract class Generator{ abstract class Generator{
@ -44,7 +44,7 @@ abstract class Generator{
public static function convertSeed(string $seed) : ?int{ public static function convertSeed(string $seed) : ?int{
if($seed === ""){ //empty seed should cause a random seed to be selected - can't use 0 here because 0 is a valid seed if($seed === ""){ //empty seed should cause a random seed to be selected - can't use 0 here because 0 is a valid seed
$convertedSeed = null; $convertedSeed = null;
}elseif(ctype_digit($seed)){ //this avoids treating seeds like "404.4" as integer seeds }elseif(preg_match('/^-?\d+$/', $seed) === 1){ //this avoids treating seeds like "404.4" as integer seeds
$convertedSeed = (int) $seed; $convertedSeed = (int) $seed;
}else{ }else{
$convertedSeed = Utils::javaStringHash($seed); $convertedSeed = Utils::javaStringHash($seed);

View File

@ -48,7 +48,7 @@ class GroundCover extends Populator{
$column = $chunk->getBlockIdColumn($x, $z); $column = $chunk->getBlockIdColumn($x, $z);
for($y = 127; $y > 0; --$y){ for($y = 127; $y > 0; --$y){
if($column{$y} !== "\x00" and !BlockFactory::get(ord($column{$y}))->isTransparent()){ if($column[$y] !== "\x00" and !BlockFactory::get(ord($column[$y]))->isTransparent()){
break; break;
} }
} }
@ -56,10 +56,10 @@ class GroundCover extends Populator{
$endY = $startY - count($cover); $endY = $startY - count($cover);
for($y = $startY; $y > $endY and $y >= 0; --$y){ for($y = $startY; $y > $endY and $y >= 0; --$y){
$b = $cover[$startY - $y]; $b = $cover[$startY - $y];
if($column{$y} === "\x00" and $b->isSolid()){ if($column[$y] === "\x00" and $b->isSolid()){
break; break;
} }
if($b->canBeFlowedInto() and BlockFactory::get(ord($column{$y})) instanceof Liquid){ if($b->canBeFlowedInto() and BlockFactory::get(ord($column[$y])) instanceof Liquid){
continue; continue;
} }
if($b->getDamage() === 0){ if($b->getDamage() === 0){

View File

@ -30,7 +30,7 @@ use pocketmine\item\ItemFactory;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
use pocketmine\utils\UUID; use pocketmine\utils\UUID;
use function str_repeat; use function str_repeat;
@ -84,7 +84,7 @@ class FloatingTextParticle extends Particle{
if($this->entityId === null){ if($this->entityId === null){
$this->entityId = Entity::$entityCount++; $this->entityId = Entity::$entityCount++;
}else{ }else{
$pk0 = new RemoveEntityPacket(); $pk0 = new RemoveActorPacket();
$pk0->entityUniqueId = $this->entityId; $pk0->entityUniqueId = $this->entityId;
$p[] = $pk0; $p[] = $pk0;

View File

@ -29,59 +29,67 @@ use pocketmine\network\mcpe\protocol\DataPacket;
abstract class Particle extends Vector3{ abstract class Particle extends Vector3{
public const TYPE_BUBBLE = 1; public const TYPE_BUBBLE = 1;
public const TYPE_CRITICAL = 2; //2 same as 1
public const TYPE_BLOCK_FORCE_FIELD = 3; public const TYPE_CRITICAL = 3;
public const TYPE_SMOKE = 4; public const TYPE_BLOCK_FORCE_FIELD = 4;
public const TYPE_EXPLODE = 5; public const TYPE_SMOKE = 5;
public const TYPE_EVAPORATION = 6; public const TYPE_EXPLODE = 6;
public const TYPE_FLAME = 7; public const TYPE_EVAPORATION = 7;
public const TYPE_LAVA = 8; public const TYPE_FLAME = 8;
public const TYPE_LARGE_SMOKE = 9; public const TYPE_LAVA = 9;
public const TYPE_REDSTONE = 10; public const TYPE_LARGE_SMOKE = 10;
public const TYPE_RISING_RED_DUST = 11; public const TYPE_REDSTONE = 11;
public const TYPE_ITEM_BREAK = 12; public const TYPE_RISING_RED_DUST = 12;
public const TYPE_SNOWBALL_POOF = 13; //62 same as 12
public const TYPE_HUGE_EXPLODE = 14; public const TYPE_ITEM_BREAK = 13;
public const TYPE_HUGE_EXPLODE_SEED = 15; public const TYPE_SNOWBALL_POOF = 14;
public const TYPE_MOB_FLAME = 16; public const TYPE_HUGE_EXPLODE = 15;
public const TYPE_HEART = 17; //60 same as 15
public const TYPE_TERRAIN = 18; public const TYPE_HUGE_EXPLODE_SEED = 16;
public const TYPE_SUSPENDED_TOWN = 19, TYPE_TOWN_AURA = 19; public const TYPE_MOB_FLAME = 17;
public const TYPE_PORTAL = 20; public const TYPE_HEART = 18;
public const TYPE_SPLASH = 21, TYPE_WATER_SPLASH = 21; public const TYPE_TERRAIN = 19;
public const TYPE_WATER_WAKE = 22; public const TYPE_SUSPENDED_TOWN = 20, TYPE_TOWN_AURA = 20;
public const TYPE_DRIP_WATER = 23; //61 same as 20
public const TYPE_DRIP_LAVA = 24; public const TYPE_PORTAL = 21;
public const TYPE_FALLING_DUST = 25, TYPE_DUST = 25; //22 same as 21
public const TYPE_MOB_SPELL = 26; public const TYPE_SPLASH = 23, TYPE_WATER_SPLASH = 23;
public const TYPE_MOB_SPELL_AMBIENT = 27; //24 same as 23
public const TYPE_MOB_SPELL_INSTANTANEOUS = 28; public const TYPE_WATER_WAKE = 25;
public const TYPE_INK = 29; public const TYPE_DRIP_WATER = 26;
public const TYPE_SLIME = 30; public const TYPE_DRIP_LAVA = 27;
public const TYPE_RAIN_SPLASH = 31; public const TYPE_FALLING_DUST = 28, TYPE_DUST = 28;
public const TYPE_VILLAGER_ANGRY = 32; public const TYPE_MOB_SPELL = 29;
public const TYPE_VILLAGER_HAPPY = 33; public const TYPE_MOB_SPELL_AMBIENT = 30;
public const TYPE_ENCHANTMENT_TABLE = 34; public const TYPE_MOB_SPELL_INSTANTANEOUS = 31;
public const TYPE_TRACKING_EMITTER = 35; public const TYPE_INK = 32;
public const TYPE_NOTE = 36; public const TYPE_SLIME = 33;
public const TYPE_WITCH_SPELL = 37; public const TYPE_RAIN_SPLASH = 34;
public const TYPE_CARROT = 38; public const TYPE_VILLAGER_ANGRY = 35;
//39 unknown //59 same as 35
public const TYPE_END_ROD = 40; public const TYPE_VILLAGER_HAPPY = 36;
public const TYPE_DRAGONS_BREATH = 41; public const TYPE_ENCHANTMENT_TABLE = 37;
public const TYPE_SPIT = 42; public const TYPE_TRACKING_EMITTER = 38;
public const TYPE_TOTEM = 43; public const TYPE_NOTE = 39;
public const TYPE_FOOD = 44; public const TYPE_WITCH_SPELL = 40;
public const TYPE_FIREWORKS_STARTER = 45; public const TYPE_CARROT = 41;
public const TYPE_FIREWORKS_SPARK = 46; //42 unknown
public const TYPE_FIREWORKS_OVERLAY = 47; public const TYPE_END_ROD = 43;
public const TYPE_BALLOON_GAS = 48; //58 same as 43
public const TYPE_COLORED_FLAME = 49; public const TYPE_DRAGONS_BREATH = 44;
public const TYPE_SPARKLER = 50; public const TYPE_SPIT = 45;
public const TYPE_CONDUIT = 51; public const TYPE_TOTEM = 46;
public const TYPE_BUBBLE_COLUMN_UP = 52; public const TYPE_FOOD = 47;
public const TYPE_BUBBLE_COLUMN_DOWN = 53; public const TYPE_FIREWORKS_STARTER = 48;
public const TYPE_SNEEZE = 54; public const TYPE_FIREWORKS_SPARK = 49;
public const TYPE_FIREWORKS_OVERLAY = 50;
public const TYPE_BALLOON_GAS = 51;
public const TYPE_COLORED_FLAME = 52;
public const TYPE_SPARKLER = 53;
public const TYPE_CONDUIT = 54;
public const TYPE_BUBBLE_COLUMN_UP = 55;
public const TYPE_BUBBLE_COLUMN_DOWN = 56;
public const TYPE_SNEEZE = 57;
/** /**
* @return DataPacket|DataPacket[] * @return DataPacket|DataPacket[]

View File

@ -27,12 +27,14 @@ namespace pocketmine\network\mcpe;
use pocketmine\entity\Attribute; use pocketmine\entity\Attribute;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\item\Durable;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;
use pocketmine\item\ItemIds; use pocketmine\item\ItemIds;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\NetworkLittleEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\CommandOriginData;
use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\network\mcpe\protocol\types\EntityLink;
use pocketmine\utils\BinaryStream; use pocketmine\utils\BinaryStream;
@ -42,6 +44,9 @@ use function strlen;
class NetworkBinaryStream extends BinaryStream{ class NetworkBinaryStream extends BinaryStream{
private const DAMAGE_TAG = "Damage"; //TAG_Int
private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___";
public function getString() : string{ public function getString() : string{
return $this->get($this->getUnsignedVarInt()); return $this->get($this->getUnsignedVarInt());
} }
@ -76,15 +81,12 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = $this->getVarInt(); $auxValue = $this->getVarInt();
$data = $auxValue >> 8; $data = $auxValue >> 8;
if($data === 0x7fff){
$data = -1;
}
$cnt = $auxValue & 0xff; $cnt = $auxValue & 0xff;
$nbtLen = $this->getLShort(); $nbtLen = $this->getLShort();
/** @var CompoundTag|string $nbt */ /** @var CompoundTag|null $nbt */
$nbt = ""; $nbt = null;
if($nbtLen === 0xffff){ if($nbtLen === 0xffff){
$c = $this->getByte(); $c = $this->getByte();
if($c !== 1){ if($c !== 1){
@ -108,7 +110,22 @@ class NetworkBinaryStream extends BinaryStream{
if($id === ItemIds::SHIELD){ if($id === ItemIds::SHIELD){
$this->getVarLong(); //"blocking tick" (ffs mojang) $this->getVarLong(); //"blocking tick" (ffs mojang)
} }
if($nbt !== null){
if($nbt->hasTag(self::DAMAGE_TAG, IntTag::class)){
$data = $nbt->getInt(self::DAMAGE_TAG);
$nbt->removeTag(self::DAMAGE_TAG);
if($nbt->count() === 0){
$nbt = null;
goto end;
}
}
if(($conflicted = $nbt->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){
$nbt->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
$conflicted->setName(self::DAMAGE_TAG);
$nbt->setTag($conflicted);
}
}
end:
return ItemFactory::get($id, $data, $cnt, $nbt); return ItemFactory::get($id, $data, $cnt, $nbt);
} }
@ -124,10 +141,27 @@ class NetworkBinaryStream extends BinaryStream{
$auxValue = (($item->getDamage() & 0x7fff) << 8) | $item->getCount(); $auxValue = (($item->getDamage() & 0x7fff) << 8) | $item->getCount();
$this->putVarInt($auxValue); $this->putVarInt($auxValue);
$nbt = null;
if($item->hasCompoundTag()){ if($item->hasCompoundTag()){
$nbt = clone $item->getNamedTag();
}
if($item instanceof Durable and $item->getDamage() > 0){
if($nbt !== null){
if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){
$nbt->removeTag(self::DAMAGE_TAG);
$existing->setName(self::DAMAGE_TAG_CONFLICT_RESOLUTION);
$nbt->setTag($existing);
}
}else{
$nbt = new CompoundTag();
}
$nbt->setInt(self::DAMAGE_TAG, $item->getDamage());
}
if($nbt !== null){
$this->putLShort(0xffff); $this->putLShort(0xffff);
$this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0 $this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0
$this->put((new NetworkLittleEndianNBTStream())->write($item->getNamedTag())); $this->put((new NetworkLittleEndianNBTStream())->write($nbt));
}else{ }else{
$this->putLShort(0); $this->putLShort(0);
} }
@ -140,6 +174,29 @@ class NetworkBinaryStream extends BinaryStream{
} }
} }
public function getRecipeIngredient() : Item{
$id = $this->getVarInt();
if($id === 0){
return ItemFactory::get(ItemIds::AIR, 0, 0);
}
$meta = $this->getVarInt();
if($meta === 0x7fff){
$meta = -1;
}
$count = $this->getVarInt();
return ItemFactory::get($id, $meta, $count);
}
public function putRecipeIngredient(Item $item) : void{
if($item->isNull()){
$this->putVarInt(0);
}else{
$this->putVarInt($item->getId());
$this->putVarInt($item->getDamage() & 0x7fff);
$this->putVarInt($item->getCount());
}
}
/** /**
* Decodes entity metadata from the stream. * Decodes entity metadata from the stream.
* *

View File

@ -23,18 +23,22 @@ declare(strict_types=1);
namespace pocketmine\network\mcpe; namespace pocketmine\network\mcpe;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\ActorFallPacket;
use pocketmine\network\mcpe\protocol\ActorPickRequestPacket;
use pocketmine\network\mcpe\protocol\AddActorPacket;
use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket; use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket;
use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\AddEntityPacket;
use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\AddItemActorPacket;
use pocketmine\network\mcpe\protocol\AddPaintingPacket; use pocketmine\network\mcpe\protocol\AddPaintingPacket;
use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\AutomationClientConnectPacket; use pocketmine\network\mcpe\protocol\AutomationClientConnectPacket;
use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket;
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
use pocketmine\network\mcpe\protocol\AvailableEntityIdentifiersPacket;
use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\BookEditPacket;
@ -43,6 +47,9 @@ use pocketmine\network\mcpe\protocol\CameraPacket;
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket;
use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket;
use pocketmine\network\mcpe\protocol\ClientCacheStatusPacket;
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\CommandOutputPacket; use pocketmine\network\mcpe\protocol\CommandOutputPacket;
@ -54,12 +61,8 @@ use pocketmine\network\mcpe\protocol\CraftingDataPacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\EntityFallPacket;
use pocketmine\network\mcpe\protocol\EntityPickRequestPacket;
use pocketmine\network\mcpe\protocol\EventPacket; use pocketmine\network\mcpe\protocol\EventPacket;
use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\ExplodePacket;
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; use pocketmine\network\mcpe\protocol\GameRulesChangedPacket;
use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket; use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket;
use pocketmine\network\mcpe\protocol\HurtArmorPacket; use pocketmine\network\mcpe\protocol\HurtArmorPacket;
@ -70,6 +73,8 @@ use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
use pocketmine\network\mcpe\protocol\LabTablePacket; use pocketmine\network\mcpe\protocol\LabTablePacket;
use pocketmine\network\mcpe\protocol\LecternUpdatePacket; use pocketmine\network\mcpe\protocol\LecternUpdatePacket;
use pocketmine\network\mcpe\protocol\LevelChunkPacket;
use pocketmine\network\mcpe\protocol\LevelEventGenericPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1; use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1;
@ -82,8 +87,8 @@ use pocketmine\network\mcpe\protocol\MobEffectPacket;
use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;
use pocketmine\network\mcpe\protocol\ModalFormResponsePacket; use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket;
use pocketmine\network\mcpe\protocol\MoveEntityDeltaPacket; use pocketmine\network\mcpe\protocol\MoveActorDeltaPacket;
use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket;
use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket;
use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket; use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket;
@ -98,6 +103,7 @@ use pocketmine\network\mcpe\protocol\PlayerSkinPacket;
use pocketmine\network\mcpe\protocol\PlaySoundPacket; use pocketmine\network\mcpe\protocol\PlaySoundPacket;
use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket;
use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket; use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket;
use pocketmine\network\mcpe\protocol\RemoveActorPacket;
use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
use pocketmine\network\mcpe\protocol\RemoveObjectivePacket; use pocketmine\network\mcpe\protocol\RemoveObjectivePacket;
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
@ -113,13 +119,13 @@ use pocketmine\network\mcpe\protocol\ScriptCustomEventPacket;
use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket;
use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket; use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket;
use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket;
use pocketmine\network\mcpe\protocol\SetActorDataPacket;
use pocketmine\network\mcpe\protocol\SetActorLinkPacket;
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket; use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket;
use pocketmine\network\mcpe\protocol\SetDefaultGameTypePacket; use pocketmine\network\mcpe\protocol\SetDefaultGameTypePacket;
use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
use pocketmine\network\mcpe\protocol\SetDisplayObjectivePacket; use pocketmine\network\mcpe\protocol\SetDisplayObjectivePacket;
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
use pocketmine\network\mcpe\protocol\SetEntityLinkPacket;
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
use pocketmine\network\mcpe\protocol\SetHealthPacket; use pocketmine\network\mcpe\protocol\SetHealthPacket;
use pocketmine\network\mcpe\protocol\SetLastHurtByPacket; use pocketmine\network\mcpe\protocol\SetLastHurtByPacket;
use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket;
@ -138,12 +144,15 @@ use pocketmine\network\mcpe\protocol\SpawnParticleEffectPacket;
use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\StartGamePacket;
use pocketmine\network\mcpe\protocol\StopSoundPacket; use pocketmine\network\mcpe\protocol\StopSoundPacket;
use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket;
use pocketmine\network\mcpe\protocol\StructureTemplateDataExportRequestPacket;
use pocketmine\network\mcpe\protocol\StructureTemplateDataExportResponsePacket;
use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket;
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket;
use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TextPacket;
use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\TransferPacket;
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockPropertiesPacket;
use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket; use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket;
use pocketmine\network\mcpe\protocol\UpdateEquipPacket; use pocketmine\network\mcpe\protocol\UpdateEquipPacket;
use pocketmine\network\mcpe\protocol\UpdateSoftEnumPacket; use pocketmine\network\mcpe\protocol\UpdateSoftEnumPacket;
@ -202,23 +211,23 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleAddEntity(AddEntityPacket $packet) : bool{ public function handleAddActor(AddActorPacket $packet) : bool{
return false; return false;
} }
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{ public function handleRemoveActor(RemoveActorPacket $packet) : bool{
return false; return false;
} }
public function handleAddItemEntity(AddItemEntityPacket $packet) : bool{ public function handleAddItemActor(AddItemActorPacket $packet) : bool{
return false; return false;
} }
public function handleTakeItemEntity(TakeItemEntityPacket $packet) : bool{ public function handleTakeItemActor(TakeItemActorPacket $packet) : bool{
return false; return false;
} }
public function handleMoveEntityAbsolute(MoveEntityAbsolutePacket $packet) : bool{ public function handleMoveActorAbsolute(MoveActorAbsolutePacket $packet) : bool{
return false; return false;
} }
@ -254,7 +263,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleEntityEvent(EntityEventPacket $packet) : bool{ public function handleActorEvent(ActorEventPacket $packet) : bool{
return false; return false;
} }
@ -286,7 +295,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{
return false; return false;
} }
@ -294,7 +303,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleEntityFall(EntityFallPacket $packet) : bool{ public function handleActorFall(ActorFallPacket $packet) : bool{
return false; return false;
} }
@ -302,15 +311,15 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleSetEntityData(SetEntityDataPacket $packet) : bool{ public function handleSetActorData(SetActorDataPacket $packet) : bool{
return false; return false;
} }
public function handleSetEntityMotion(SetEntityMotionPacket $packet) : bool{ public function handleSetActorMotion(SetActorMotionPacket $packet) : bool{
return false; return false;
} }
public function handleSetEntityLink(SetEntityLinkPacket $packet) : bool{ public function handleSetActorLink(SetActorLinkPacket $packet) : bool{
return false; return false;
} }
@ -370,7 +379,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
return false; return false;
} }
@ -378,7 +387,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleFullChunkData(FullChunkDataPacket $packet) : bool{ public function handleLevelChunk(LevelChunkPacket $packet) : bool{
return false; return false;
} }
@ -590,7 +599,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleMoveEntityDelta(MoveEntityDeltaPacket $packet) : bool{ public function handleMoveActorDelta(MoveActorDeltaPacket $packet) : bool{
return false; return false;
} }
@ -618,7 +627,7 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleAvailableEntityIdentifiers(AvailableEntityIdentifiersPacket $packet) : bool{ public function handleAvailableActorIdentifiers(AvailableActorIdentifiersPacket $packet) : bool{
return false; return false;
} }
@ -638,6 +647,10 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleLevelEventGeneric(LevelEventGenericPacket $packet) : bool{
return false;
}
public function handleLecternUpdate(LecternUpdatePacket $packet) : bool{ public function handleLecternUpdate(LecternUpdatePacket $packet) : bool{
return false; return false;
} }
@ -646,11 +659,43 @@ abstract class NetworkSession{
return false; return false;
} }
public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{ public function handleAddEntity(AddEntityPacket $packet) : bool{
return false;
}
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{
return false;
}
public function handleClientCacheStatus(ClientCacheStatusPacket $packet) : bool{
return false; return false;
} }
public function handleOnScreenTextureAnimation(OnScreenTextureAnimationPacket $packet) : bool{ public function handleOnScreenTextureAnimation(OnScreenTextureAnimationPacket $packet) : bool{
return false; return false;
} }
public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{
return false;
}
public function handleStructureTemplateDataExportRequest(StructureTemplateDataExportRequestPacket $packet) : bool{
return false;
}
public function handleStructureTemplateDataExportResponse(StructureTemplateDataExportResponsePacket $packet) : bool{
return false;
}
public function handleUpdateBlockProperties(UpdateBlockPropertiesPacket $packet) : bool{
return false;
}
public function handleClientCacheBlobStatus(ClientCacheBlobStatusPacket $packet) : bool{
return false;
}
public function handleClientCacheMissResponse(ClientCacheMissResponsePacket $packet) : bool{
return false;
}
} }

View File

@ -25,9 +25,12 @@ namespace pocketmine\network\mcpe;
use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\ActorFallPacket;
use pocketmine\network\mcpe\protocol\ActorPickRequestPacket;
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AnimatePacket;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\BookEditPacket;
use pocketmine\network\mcpe\protocol\BossEventPacket; use pocketmine\network\mcpe\protocol\BossEventPacket;
@ -37,9 +40,6 @@ use pocketmine\network\mcpe\protocol\CommandRequestPacket;
use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket;
use pocketmine\network\mcpe\protocol\CraftingEventPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket;
use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DataPacket;
use pocketmine\network\mcpe\protocol\EntityEventPacket;
use pocketmine\network\mcpe\protocol\EntityFallPacket;
use pocketmine\network\mcpe\protocol\EntityPickRequestPacket;
use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InteractPacket;
use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket;
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
@ -142,7 +142,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
return true; //useless leftover from 1.8 return true; //useless leftover from 1.8
} }
public function handleEntityEvent(EntityEventPacket $packet) : bool{ public function handleActorEvent(ActorEventPacket $packet) : bool{
return $this->player->handleEntityEvent($packet); return $this->player->handleEntityEvent($packet);
} }
@ -166,7 +166,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
return $this->player->handleBlockPickRequest($packet); return $this->player->handleBlockPickRequest($packet);
} }
public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{
return false; //TODO return false; //TODO
} }
@ -174,7 +174,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
return $this->player->handlePlayerAction($packet); return $this->player->handlePlayerAction($packet);
} }
public function handleEntityFall(EntityFallPacket $packet) : bool{ public function handleActorFall(ActorFallPacket $packet) : bool{
return true; //Not used return true; //Not used
} }
@ -198,7 +198,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{
return $this->player->handleAdventureSettings($packet); return $this->player->handleAdventureSettings($packet);
} }
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
return $this->player->handleBlockEntityData($packet); return $this->player->handleBlockEntityData($packet);
} }

View File

@ -120,12 +120,12 @@ class VerifyLoginTask extends AsyncTask{
[$rString, $sString] = str_split($plainSignature, 48); [$rString, $sString] = str_split($plainSignature, 48);
$rString = ltrim($rString, "\x00"); $rString = ltrim($rString, "\x00");
if(ord($rString{0}) >= 128){ //Would be considered signed, pad it with an extra zero if(ord($rString[0]) >= 128){ //Would be considered signed, pad it with an extra zero
$rString = "\x00" . $rString; $rString = "\x00" . $rString;
} }
$sString = ltrim($sString, "\x00"); $sString = ltrim($sString, "\x00");
if(ord($sString{0}) >= 128){ //Would be considered signed, pad it with an extra zero if(ord($sString[0]) >= 128){ //Would be considered signed, pad it with an extra zero
$sString = "\x00" . $sString; $sString = "\x00" . $sString;
} }

View File

@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class EntityEventPacket extends DataPacket{ class ActorEventPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_EVENT_PACKET; public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET;
public const HURT_ANIMATION = 2; public const HURT_ANIMATION = 2;
public const DEATH_ANIMATION = 3; public const DEATH_ANIMATION = 3;
@ -103,6 +103,6 @@ class EntityEventPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleEntityEvent($this); return $session->handleActorEvent($this);
} }
} }

View File

@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class EntityFallPacket extends DataPacket{ class ActorFallPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_FALL_PACKET; public const NETWORK_ID = ProtocolInfo::ACTOR_FALL_PACKET;
/** @var int */ /** @var int */
public $entityRuntimeId; public $entityRuntimeId;
@ -51,6 +51,6 @@ class EntityFallPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleEntityFall($this); return $session->handleActorFall($this);
} }
} }

View File

@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class EntityPickRequestPacket extends DataPacket{ class ActorPickRequestPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ENTITY_PICK_REQUEST_PACKET; public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET;
/** @var int */ /** @var int */
public $entityUniqueId; public $entityUniqueId;
@ -46,6 +46,6 @@ class EntityPickRequestPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleEntityPickRequest($this); return $session->handleActorPickRequest($this);
} }
} }

View File

@ -0,0 +1,240 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\entity\Attribute;
use pocketmine\entity\EntityIds;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use function array_search;
use function count;
class AddActorPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ACTOR_PACKET;
/*
* Really really really really really nasty hack, to preserve backwards compatibility.
* We can't transition to string IDs within 3.x because the network IDs (the integer ones) are exposed
* to the API in some places (for god's sake shoghi).
*
* TODO: remove this on 4.0
*/
public const LEGACY_ID_MAP_BC = [
EntityIds::NPC => "minecraft:npc",
EntityIds::PLAYER => "minecraft:player",
EntityIds::WITHER_SKELETON => "minecraft:wither_skeleton",
EntityIds::HUSK => "minecraft:husk",
EntityIds::STRAY => "minecraft:stray",
EntityIds::WITCH => "minecraft:witch",
EntityIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager",
EntityIds::BLAZE => "minecraft:blaze",
EntityIds::MAGMA_CUBE => "minecraft:magma_cube",
EntityIds::GHAST => "minecraft:ghast",
EntityIds::CAVE_SPIDER => "minecraft:cave_spider",
EntityIds::SILVERFISH => "minecraft:silverfish",
EntityIds::ENDERMAN => "minecraft:enderman",
EntityIds::SLIME => "minecraft:slime",
EntityIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman",
EntityIds::SPIDER => "minecraft:spider",
EntityIds::SKELETON => "minecraft:skeleton",
EntityIds::CREEPER => "minecraft:creeper",
EntityIds::ZOMBIE => "minecraft:zombie",
EntityIds::SKELETON_HORSE => "minecraft:skeleton_horse",
EntityIds::MULE => "minecraft:mule",
EntityIds::DONKEY => "minecraft:donkey",
EntityIds::DOLPHIN => "minecraft:dolphin",
EntityIds::TROPICALFISH => "minecraft:tropicalfish",
EntityIds::WOLF => "minecraft:wolf",
EntityIds::SQUID => "minecraft:squid",
EntityIds::DROWNED => "minecraft:drowned",
EntityIds::SHEEP => "minecraft:sheep",
EntityIds::MOOSHROOM => "minecraft:mooshroom",
EntityIds::PANDA => "minecraft:panda",
EntityIds::SALMON => "minecraft:salmon",
EntityIds::PIG => "minecraft:pig",
EntityIds::VILLAGER => "minecraft:villager",
EntityIds::COD => "minecraft:cod",
EntityIds::PUFFERFISH => "minecraft:pufferfish",
EntityIds::COW => "minecraft:cow",
EntityIds::CHICKEN => "minecraft:chicken",
EntityIds::BALLOON => "minecraft:balloon",
EntityIds::LLAMA => "minecraft:llama",
EntityIds::IRON_GOLEM => "minecraft:iron_golem",
EntityIds::RABBIT => "minecraft:rabbit",
EntityIds::SNOW_GOLEM => "minecraft:snow_golem",
EntityIds::BAT => "minecraft:bat",
EntityIds::OCELOT => "minecraft:ocelot",
EntityIds::HORSE => "minecraft:horse",
EntityIds::CAT => "minecraft:cat",
EntityIds::POLAR_BEAR => "minecraft:polar_bear",
EntityIds::ZOMBIE_HORSE => "minecraft:zombie_horse",
EntityIds::TURTLE => "minecraft:turtle",
EntityIds::PARROT => "minecraft:parrot",
EntityIds::GUARDIAN => "minecraft:guardian",
EntityIds::ELDER_GUARDIAN => "minecraft:elder_guardian",
EntityIds::VINDICATOR => "minecraft:vindicator",
EntityIds::WITHER => "minecraft:wither",
EntityIds::ENDER_DRAGON => "minecraft:ender_dragon",
EntityIds::SHULKER => "minecraft:shulker",
EntityIds::ENDERMITE => "minecraft:endermite",
EntityIds::MINECART => "minecraft:minecart",
EntityIds::HOPPER_MINECART => "minecraft:hopper_minecart",
EntityIds::TNT_MINECART => "minecraft:tnt_minecart",
EntityIds::CHEST_MINECART => "minecraft:chest_minecart",
EntityIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart",
EntityIds::ARMOR_STAND => "minecraft:armor_stand",
EntityIds::ITEM => "minecraft:item",
EntityIds::TNT => "minecraft:tnt",
EntityIds::FALLING_BLOCK => "minecraft:falling_block",
EntityIds::XP_BOTTLE => "minecraft:xp_bottle",
EntityIds::XP_ORB => "minecraft:xp_orb",
EntityIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal",
EntityIds::ENDER_CRYSTAL => "minecraft:ender_crystal",
EntityIds::SHULKER_BULLET => "minecraft:shulker_bullet",
EntityIds::FISHING_HOOK => "minecraft:fishing_hook",
EntityIds::DRAGON_FIREBALL => "minecraft:dragon_fireball",
EntityIds::ARROW => "minecraft:arrow",
EntityIds::SNOWBALL => "minecraft:snowball",
EntityIds::EGG => "minecraft:egg",
EntityIds::PAINTING => "minecraft:painting",
EntityIds::THROWN_TRIDENT => "minecraft:thrown_trident",
EntityIds::FIREBALL => "minecraft:fireball",
EntityIds::SPLASH_POTION => "minecraft:splash_potion",
EntityIds::ENDER_PEARL => "minecraft:ender_pearl",
EntityIds::LEASH_KNOT => "minecraft:leash_knot",
EntityIds::WITHER_SKULL => "minecraft:wither_skull",
EntityIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous",
EntityIds::BOAT => "minecraft:boat",
EntityIds::LIGHTNING_BOLT => "minecraft:lightning_bolt",
EntityIds::SMALL_FIREBALL => "minecraft:small_fireball",
EntityIds::LLAMA_SPIT => "minecraft:llama_spit",
EntityIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud",
EntityIds::LINGERING_POTION => "minecraft:lingering_potion",
EntityIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket",
EntityIds::EVOCATION_FANG => "minecraft:evocation_fang",
EntityIds::EVOCATION_ILLAGER => "minecraft:evocation_illager",
EntityIds::VEX => "minecraft:vex",
EntityIds::AGENT => "minecraft:agent",
EntityIds::ICE_BOMB => "minecraft:ice_bomb",
EntityIds::PHANTOM => "minecraft:phantom",
EntityIds::TRIPOD_CAMERA => "minecraft:tripod_camera"
];
/** @var int|null */
public $entityUniqueId = null; //TODO
/** @var int */
public $entityRuntimeId;
/** @var int */
public $type;
/** @var Vector3 */
public $position;
/** @var Vector3|null */
public $motion;
/** @var float */
public $pitch = 0.0;
/** @var float */
public $yaw = 0.0;
/** @var float */
public $headYaw = 0.0;
/** @var Attribute[] */
public $attributes = [];
/** @var array */
public $metadata = [];
/** @var EntityLink[] */
public $links = [];
protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
$this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true);
if($this->type === false){
throw new \UnexpectedValueException("Can't map ID $t to legacy ID");
}
$this->position = $this->getVector3();
$this->motion = $this->getVector3();
$this->pitch = $this->getLFloat();
$this->yaw = $this->getLFloat();
$this->headYaw = $this->getLFloat();
$attrCount = $this->getUnsignedVarInt();
for($i = 0; $i < $attrCount; ++$i){
$name = $this->getString();
$min = $this->getLFloat();
$current = $this->getLFloat();
$max = $this->getLFloat();
$attr = Attribute::getAttributeByName($name);
if($attr !== null){
$attr->setMinValue($min);
$attr->setMaxValue($max);
$attr->setValue($current);
$this->attributes[] = $attr;
}else{
throw new \UnexpectedValueException("Unknown attribute type \"$name\"");
}
}
$this->metadata = $this->getEntityMetadata();
$linkCount = $this->getUnsignedVarInt();
for($i = 0; $i < $linkCount; ++$i){
$this->links[] = $this->getEntityLink();
}
}
protected function encodePayload(){
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId);
$this->putEntityRuntimeId($this->entityRuntimeId);
if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){
throw new \InvalidArgumentException("Unknown entity numeric ID $this->type");
}
$this->putString(self::LEGACY_ID_MAP_BC[$this->type]);
$this->putVector3($this->position);
$this->putVector3Nullable($this->motion);
$this->putLFloat($this->pitch);
$this->putLFloat($this->yaw);
$this->putLFloat($this->headYaw);
$this->putUnsignedVarInt(count($this->attributes));
foreach($this->attributes as $attribute){
$this->putString($attribute->getName());
$this->putLFloat($attribute->getMinValue());
$this->putLFloat($attribute->getValue());
$this->putLFloat($attribute->getMaxValue());
}
$this->putEntityMetadata($this->metadata);
$this->putUnsignedVarInt(count($this->links));
foreach($this->links as $link){
$this->putEntityLink($link);
}
}
public function handle(NetworkSession $session) : bool{
return $session->handleAddActor($this);
}
}

View File

@ -25,216 +25,36 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h> #include <rules/DataPacket.h>
use pocketmine\entity\Attribute;
use pocketmine\entity\EntityIds;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\EntityLink;
use function array_search;
use function count;
class AddEntityPacket extends DataPacket{ class AddEntityPacket extends DataPacket/* implements ClientboundPacket*/{
public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET;
/* /** @var int */
* Really really really really really nasty hack, to preserve backwards compatibility. private $uvarint1;
* We can't transition to string IDs within 3.x because the network IDs (the integer ones) are exposed
* to the API in some places (for god's sake shoghi). public static function create(int $uvarint1) : self{
* $result = new self;
* TODO: remove this on 4.0 $result->uvarint1 = $uvarint1;
return $result;
}
/**
* @return int
*/ */
public const LEGACY_ID_MAP_BC = [ public function getUvarint1() : int{
EntityIds::NPC => "minecraft:npc", return $this->uvarint1;
EntityIds::PLAYER => "minecraft:player",
EntityIds::WITHER_SKELETON => "minecraft:wither_skeleton",
EntityIds::HUSK => "minecraft:husk",
EntityIds::STRAY => "minecraft:stray",
EntityIds::WITCH => "minecraft:witch",
EntityIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager",
EntityIds::BLAZE => "minecraft:blaze",
EntityIds::MAGMA_CUBE => "minecraft:magma_cube",
EntityIds::GHAST => "minecraft:ghast",
EntityIds::CAVE_SPIDER => "minecraft:cave_spider",
EntityIds::SILVERFISH => "minecraft:silverfish",
EntityIds::ENDERMAN => "minecraft:enderman",
EntityIds::SLIME => "minecraft:slime",
EntityIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman",
EntityIds::SPIDER => "minecraft:spider",
EntityIds::SKELETON => "minecraft:skeleton",
EntityIds::CREEPER => "minecraft:creeper",
EntityIds::ZOMBIE => "minecraft:zombie",
EntityIds::SKELETON_HORSE => "minecraft:skeleton_horse",
EntityIds::MULE => "minecraft:mule",
EntityIds::DONKEY => "minecraft:donkey",
EntityIds::DOLPHIN => "minecraft:dolphin",
EntityIds::TROPICALFISH => "minecraft:tropicalfish",
EntityIds::WOLF => "minecraft:wolf",
EntityIds::SQUID => "minecraft:squid",
EntityIds::DROWNED => "minecraft:drowned",
EntityIds::SHEEP => "minecraft:sheep",
EntityIds::MOOSHROOM => "minecraft:mooshroom",
EntityIds::PANDA => "minecraft:panda",
EntityIds::SALMON => "minecraft:salmon",
EntityIds::PIG => "minecraft:pig",
EntityIds::VILLAGER => "minecraft:villager",
EntityIds::COD => "minecraft:cod",
EntityIds::PUFFERFISH => "minecraft:pufferfish",
EntityIds::COW => "minecraft:cow",
EntityIds::CHICKEN => "minecraft:chicken",
EntityIds::BALLOON => "minecraft:balloon",
EntityIds::LLAMA => "minecraft:llama",
EntityIds::IRON_GOLEM => "minecraft:iron_golem",
EntityIds::RABBIT => "minecraft:rabbit",
EntityIds::SNOW_GOLEM => "minecraft:snow_golem",
EntityIds::BAT => "minecraft:bat",
EntityIds::OCELOT => "minecraft:ocelot",
EntityIds::HORSE => "minecraft:horse",
EntityIds::CAT => "minecraft:cat",
EntityIds::POLAR_BEAR => "minecraft:polar_bear",
EntityIds::ZOMBIE_HORSE => "minecraft:zombie_horse",
EntityIds::TURTLE => "minecraft:turtle",
EntityIds::PARROT => "minecraft:parrot",
EntityIds::GUARDIAN => "minecraft:guardian",
EntityIds::ELDER_GUARDIAN => "minecraft:elder_guardian",
EntityIds::VINDICATOR => "minecraft:vindicator",
EntityIds::WITHER => "minecraft:wither",
EntityIds::ENDER_DRAGON => "minecraft:ender_dragon",
EntityIds::SHULKER => "minecraft:shulker",
EntityIds::ENDERMITE => "minecraft:endermite",
EntityIds::MINECART => "minecraft:minecart",
EntityIds::HOPPER_MINECART => "minecraft:hopper_minecart",
EntityIds::TNT_MINECART => "minecraft:tnt_minecart",
EntityIds::CHEST_MINECART => "minecraft:chest_minecart",
EntityIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart",
EntityIds::ARMOR_STAND => "minecraft:armor_stand",
EntityIds::ITEM => "minecraft:item",
EntityIds::TNT => "minecraft:tnt",
EntityIds::FALLING_BLOCK => "minecraft:falling_block",
EntityIds::XP_BOTTLE => "minecraft:xp_bottle",
EntityIds::XP_ORB => "minecraft:xp_orb",
EntityIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal",
EntityIds::ENDER_CRYSTAL => "minecraft:ender_crystal",
EntityIds::SHULKER_BULLET => "minecraft:shulker_bullet",
EntityIds::FISHING_HOOK => "minecraft:fishing_hook",
EntityIds::DRAGON_FIREBALL => "minecraft:dragon_fireball",
EntityIds::ARROW => "minecraft:arrow",
EntityIds::SNOWBALL => "minecraft:snowball",
EntityIds::EGG => "minecraft:egg",
EntityIds::PAINTING => "minecraft:painting",
EntityIds::THROWN_TRIDENT => "minecraft:thrown_trident",
EntityIds::FIREBALL => "minecraft:fireball",
EntityIds::SPLASH_POTION => "minecraft:splash_potion",
EntityIds::ENDER_PEARL => "minecraft:ender_pearl",
EntityIds::LEASH_KNOT => "minecraft:leash_knot",
EntityIds::WITHER_SKULL => "minecraft:wither_skull",
EntityIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous",
EntityIds::BOAT => "minecraft:boat",
EntityIds::LIGHTNING_BOLT => "minecraft:lightning_bolt",
EntityIds::SMALL_FIREBALL => "minecraft:small_fireball",
EntityIds::LLAMA_SPIT => "minecraft:llama_spit",
EntityIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud",
EntityIds::LINGERING_POTION => "minecraft:lingering_potion",
EntityIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket",
EntityIds::EVOCATION_FANG => "minecraft:evocation_fang",
EntityIds::EVOCATION_ILLAGER => "minecraft:evocation_illager",
EntityIds::VEX => "minecraft:vex",
EntityIds::AGENT => "minecraft:agent",
EntityIds::ICE_BOMB => "minecraft:ice_bomb",
EntityIds::PHANTOM => "minecraft:phantom",
EntityIds::TRIPOD_CAMERA => "minecraft:tripod_camera"
];
/** @var int|null */
public $entityUniqueId = null; //TODO
/** @var int */
public $entityRuntimeId;
/** @var int */
public $type;
/** @var Vector3 */
public $position;
/** @var Vector3|null */
public $motion;
/** @var float */
public $pitch = 0.0;
/** @var float */
public $yaw = 0.0;
/** @var float */
public $headYaw = 0.0;
/** @var Attribute[] */
public $attributes = [];
/** @var array */
public $metadata = [];
/** @var EntityLink[] */
public $links = [];
protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId();
$this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true);
if($this->type === false){
throw new \UnexpectedValueException("Can't map ID $t to legacy ID");
}
$this->position = $this->getVector3();
$this->motion = $this->getVector3();
$this->pitch = $this->getLFloat();
$this->yaw = $this->getLFloat();
$this->headYaw = $this->getLFloat();
$attrCount = $this->getUnsignedVarInt();
for($i = 0; $i < $attrCount; ++$i){
$name = $this->getString();
$min = $this->getLFloat();
$current = $this->getLFloat();
$max = $this->getLFloat();
$attr = Attribute::getAttributeByName($name);
if($attr !== null){
$attr->setMinValue($min);
$attr->setMaxValue($max);
$attr->setValue($current);
$this->attributes[] = $attr;
}else{
throw new \UnexpectedValueException("Unknown attribute type \"$name\"");
}
}
$this->metadata = $this->getEntityMetadata();
$linkCount = $this->getUnsignedVarInt();
for($i = 0; $i < $linkCount; ++$i){
$this->links[] = $this->getEntityLink();
}
} }
protected function encodePayload(){ protected function decodePayload() : void{
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->uvarint1 = $this->getUnsignedVarInt();
$this->putEntityRuntimeId($this->entityRuntimeId);
if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){
throw new \InvalidArgumentException("Unknown entity numeric ID $this->type");
}
$this->putString(self::LEGACY_ID_MAP_BC[$this->type]);
$this->putVector3($this->position);
$this->putVector3Nullable($this->motion);
$this->putLFloat($this->pitch);
$this->putLFloat($this->yaw);
$this->putLFloat($this->headYaw);
$this->putUnsignedVarInt(count($this->attributes));
foreach($this->attributes as $attribute){
$this->putString($attribute->getName());
$this->putLFloat($attribute->getMinValue());
$this->putLFloat($attribute->getValue());
$this->putLFloat($attribute->getMaxValue());
}
$this->putEntityMetadata($this->metadata);
$this->putUnsignedVarInt(count($this->links));
foreach($this->links as $link){
$this->putEntityLink($link);
}
} }
public function handle(NetworkSession $session) : bool{ protected function encodePayload() : void{
return $session->handleAddEntity($this); $this->putUnsignedVarInt($this->uvarint1);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleAddEntity($this);
} }
} }

View File

@ -29,8 +29,8 @@ use pocketmine\item\Item;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class AddItemEntityPacket extends DataPacket{ class AddItemActorPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET; public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET;
/** @var int|null */ /** @var int|null */
public $entityUniqueId = null; //TODO public $entityUniqueId = null; //TODO
@ -68,6 +68,6 @@ class AddItemEntityPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleAddItemEntity($this); return $session->handleAddItemActor($this);
} }
} }

View File

@ -26,30 +26,27 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h> #include <rules/DataPacket.h>
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class AddPaintingPacket extends DataPacket{ class AddPaintingPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET;
/** @var string */
public $title;
/** @var int */
public $entityRuntimeId;
/** @var int */
public $x;
/** @var int|null */ /** @var int|null */
public $entityUniqueId = null; public $entityUniqueId = null;
/** @var int */ /** @var int */
public $y; public $entityRuntimeId;
/** @var int */ /** @var Vector3 */
public $z; public $position;
/** @var int */ /** @var int */
public $direction; public $direction;
/** @var string */
public $title;
protected function decodePayload(){ protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId(); $this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId(); $this->entityRuntimeId = $this->getEntityRuntimeId();
$this->getBlockPosition($this->x, $this->y, $this->z); $this->position = $this->getVector3();
$this->direction = $this->getVarInt(); $this->direction = $this->getVarInt();
$this->title = $this->getString(); $this->title = $this->getString();
} }
@ -57,7 +54,7 @@ class AddPaintingPacket extends DataPacket{
protected function encodePayload(){ protected function encodePayload(){
$this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId);
$this->putEntityRuntimeId($this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId);
$this->putBlockPosition($this->x, $this->y, $this->z); $this->putVector3($this->position);
$this->putVarInt($this->direction); $this->putVarInt($this->direction);
$this->putString($this->title); $this->putString($this->title);
} }

View File

@ -35,6 +35,8 @@ class AnimatePacket extends DataPacket{
public const ACTION_STOP_SLEEP = 3; public const ACTION_STOP_SLEEP = 3;
public const ACTION_CRITICAL_HIT = 4; public const ACTION_CRITICAL_HIT = 4;
public const ACTION_ROW_RIGHT = 128;
public const ACTION_ROW_LEFT = 129;
/** @var int */ /** @var int */
public $action; public $action;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class BlockEntityDataPacket extends DataPacket{ class BlockActorDataPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET; public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET;
/** @var int */ /** @var int */
public $x; public $x;
@ -51,6 +51,6 @@ class BlockEntityDataPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleBlockEntityData($this); return $session->handleBlockActorData($this);
} }
} }

View File

@ -0,0 +1,95 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
use function count;
class ClientCacheBlobStatusPacket extends DataPacket/* implements ServerboundPacket*/{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_BLOB_STATUS_PACKET;
/** @var int[] xxHash64 subchunk data hashes */
private $hitHashes = [];
/** @var int[] xxHash64 subchunk data hashes */
private $missHashes = [];
/**
* @param int[] $hitHashes
* @param int[] $missHashes
*
* @return self
*/
public static function create(array $hitHashes, array $missHashes) : self{
//type checks
(static function(int ...$hashes){})(...$hitHashes);
(static function(int ...$hashes){})(...$missHashes);
$result = new self;
$result->hitHashes = $hitHashes;
$result->missHashes = $missHashes;
return $result;
}
/**
* @return int[]
*/
public function getHitHashes() : array{
return $this->hitHashes;
}
/**
* @return int[]
*/
public function getMissHashes() : array{
return $this->missHashes;
}
protected function decodePayload() : void{
$hitCount = $this->getUnsignedVarInt();
$missCount = $this->getUnsignedVarInt();
for($i = 0; $i < $hitCount; ++$i){
$this->hitHashes[] = $this->getLLong();
}
for($i = 0; $i < $missCount; ++$i){
$this->missHashes[] = $this->getLLong();
}
}
protected function encodePayload() : void{
$this->putUnsignedVarInt(count($this->hitHashes));
$this->putUnsignedVarInt(count($this->missHashes));
foreach($this->hitHashes as $hash){
$this->putLLong($hash);
}
foreach($this->missHashes as $hash){
$this->putLLong($hash);
}
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleClientCacheBlobStatus($this);
}
}

View File

@ -0,0 +1,78 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob;
use function count;
class ClientCacheMissResponsePacket extends DataPacket/* implements ClientboundPacket*/{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_MISS_RESPONSE_PACKET;
/** @var ChunkCacheBlob[] */
private $blobs = [];
/**
* @param ChunkCacheBlob[] $blobs
*
* @return self
*/
public static function create(array $blobs) : self{
//type check
(static function(ChunkCacheBlob ...$blobs){})($blobs);
$result = new self;
$result->blobs = $blobs;
return $result;
}
/**
* @return ChunkCacheBlob[]
*/
public function getBlobs() : array{
return $this->blobs;
}
protected function decodePayload() : void{
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$hash = $this->getLLong();
$payload = $this->getString();
$this->blobs[] = new ChunkCacheBlob($hash, $payload);
}
}
protected function encodePayload() : void{
$this->putUnsignedVarInt(count($this->blobs));
foreach($this->blobs as $blob){
$this->putLLong($blob->getHash());
$this->putString($blob->getPayload());
}
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleClientCacheMissResponse($this);
}
}

View File

@ -0,0 +1,60 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class ClientCacheStatusPacket extends DataPacket/* implements ServerboundPacket*/{
public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET;
/** @var bool */
private $enabled;
public static function create(bool $enabled) : self{
$result = new self;
$result->enabled = $enabled;
return $result;
}
/**
* @return bool
*/
public function isEnabled() : bool{
return $this->enabled;
}
protected function decodePayload() : void{
$this->enabled = $this->getBool();
}
protected function encodePayload() : void{
$this->putBool($this->enabled);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleClientCacheStatus($this);
}
}

View File

@ -59,6 +59,10 @@ class CommandBlockUpdatePacket extends DataPacket{
public $name; public $name;
/** @var bool */ /** @var bool */
public $shouldTrackOutput; public $shouldTrackOutput;
/** @var int */
public $tickDelay;
/** @var bool */
public $executeOnFirstTick;
protected function decodePayload(){ protected function decodePayload(){
$this->isBlock = $this->getBool(); $this->isBlock = $this->getBool();
@ -78,6 +82,8 @@ class CommandBlockUpdatePacket extends DataPacket{
$this->name = $this->getString(); $this->name = $this->getString();
$this->shouldTrackOutput = $this->getBool(); $this->shouldTrackOutput = $this->getBool();
$this->tickDelay = $this->getLInt();
$this->executeOnFirstTick = $this->getBool();
} }
protected function encodePayload(){ protected function encodePayload(){
@ -97,6 +103,8 @@ class CommandBlockUpdatePacket extends DataPacket{
$this->putString($this->name); $this->putString($this->name);
$this->putBool($this->shouldTrackOutput); $this->putBool($this->shouldTrackOutput);
$this->putLInt($this->tickDelay);
$this->putBool($this->executeOnFirstTick);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

View File

@ -33,6 +33,9 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory; use pocketmine\item\ItemFactory;
use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
use function count; use function count;
use function str_repeat; use function str_repeat;
@ -72,11 +75,13 @@ class CraftingDataPacket extends DataPacket{
case self::ENTRY_SHAPELESS: case self::ENTRY_SHAPELESS:
case self::ENTRY_SHULKER_BOX: case self::ENTRY_SHULKER_BOX:
case self::ENTRY_SHAPELESS_CHEMISTRY: case self::ENTRY_SHAPELESS_CHEMISTRY:
$entry["recipe_id"] = $this->getString();
$ingredientCount = $this->getUnsignedVarInt(); $ingredientCount = $this->getUnsignedVarInt();
/** @var Item */ /** @var Item */
$entry["input"] = []; $entry["input"] = [];
for($j = 0; $j < $ingredientCount; ++$j){ for($j = 0; $j < $ingredientCount; ++$j){
$entry["input"][] = $this->getSlot(); $entry["input"][] = $in = $this->getRecipeIngredient();
$in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1
} }
$resultCount = $this->getUnsignedVarInt(); $resultCount = $this->getUnsignedVarInt();
$entry["output"] = []; $entry["output"] = [];
@ -85,16 +90,19 @@ class CraftingDataPacket extends DataPacket{
} }
$entry["uuid"] = $this->getUUID()->toString(); $entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString(); $entry["block"] = $this->getString();
$entry["priority"] = $this->getVarInt();
break; break;
case self::ENTRY_SHAPED: case self::ENTRY_SHAPED:
case self::ENTRY_SHAPED_CHEMISTRY: case self::ENTRY_SHAPED_CHEMISTRY:
$entry["recipe_id"] = $this->getString();
$entry["width"] = $this->getVarInt(); $entry["width"] = $this->getVarInt();
$entry["height"] = $this->getVarInt(); $entry["height"] = $this->getVarInt();
$count = $entry["width"] * $entry["height"]; $count = $entry["width"] * $entry["height"];
$entry["input"] = []; $entry["input"] = [];
for($j = 0; $j < $count; ++$j){ for($j = 0; $j < $count; ++$j){
$entry["input"][] = $this->getSlot(); $entry["input"][] = $in = $this->getRecipeIngredient();
$in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system
} }
$resultCount = $this->getUnsignedVarInt(); $resultCount = $this->getUnsignedVarInt();
$entry["output"] = []; $entry["output"] = [];
@ -103,6 +111,7 @@ class CraftingDataPacket extends DataPacket{
} }
$entry["uuid"] = $this->getUUID()->toString(); $entry["uuid"] = $this->getUUID()->toString();
$entry["block"] = $this->getString(); $entry["block"] = $this->getString();
$entry["priority"] = $this->getVarInt();
break; break;
case self::ENTRY_FURNACE: case self::ENTRY_FURNACE:
@ -116,7 +125,10 @@ class CraftingDataPacket extends DataPacket{
} }
} }
$entry["input"] = ItemFactory::get($inputId, $inputData); $entry["input"] = ItemFactory::get($inputId, $inputData);
$entry["output"] = $this->getSlot(); $entry["output"] = $out = $this->getSlot();
if($out->getDamage() === 0x7fff){
$out->setDamage(0); //TODO HACK: some 1.12 furnace recipe outputs have wildcard damage values
}
$entry["block"] = $this->getString(); $entry["block"] = $this->getString();
break; break;
@ -131,11 +143,11 @@ class CraftingDataPacket extends DataPacket{
$this->getBool(); //cleanRecipes $this->getBool(); //cleanRecipes
} }
private static function writeEntry($entry, NetworkBinaryStream $stream){ private static function writeEntry($entry, NetworkBinaryStream $stream, int $pos){
if($entry instanceof ShapelessRecipe){ if($entry instanceof ShapelessRecipe){
return self::writeShapelessRecipe($entry, $stream); return self::writeShapelessRecipe($entry, $stream, $pos);
}elseif($entry instanceof ShapedRecipe){ }elseif($entry instanceof ShapedRecipe){
return self::writeShapedRecipe($entry, $stream); return self::writeShapedRecipe($entry, $stream, $pos);
}elseif($entry instanceof FurnaceRecipe){ }elseif($entry instanceof FurnaceRecipe){
return self::writeFurnaceRecipe($entry, $stream); return self::writeFurnaceRecipe($entry, $stream);
} }
@ -144,10 +156,11 @@ class CraftingDataPacket extends DataPacket{
return -1; return -1;
} }
private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream){ private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream, int $pos){
$stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique
$stream->putUnsignedVarInt($recipe->getIngredientCount()); $stream->putUnsignedVarInt($recipe->getIngredientCount());
foreach($recipe->getIngredientList() as $item){ foreach($recipe->getIngredientList() as $item){
$stream->putSlot($item); $stream->putRecipeIngredient($item);
} }
$results = $recipe->getResults(); $results = $recipe->getResults();
@ -158,17 +171,19 @@ class CraftingDataPacket extends DataPacket{
$stream->put(str_repeat("\x00", 16)); //Null UUID $stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks) $stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
$stream->putVarInt(50); //TODO: priority
return CraftingDataPacket::ENTRY_SHAPELESS; return CraftingDataPacket::ENTRY_SHAPELESS;
} }
private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream){ private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream, int $pos){
$stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique
$stream->putVarInt($recipe->getWidth()); $stream->putVarInt($recipe->getWidth());
$stream->putVarInt($recipe->getHeight()); $stream->putVarInt($recipe->getHeight());
for($z = 0; $z < $recipe->getHeight(); ++$z){ for($z = 0; $z < $recipe->getHeight(); ++$z){
for($x = 0; $x < $recipe->getWidth(); ++$x){ for($x = 0; $x < $recipe->getWidth(); ++$x){
$stream->putSlot($recipe->getIngredient($x, $z)); $stream->putRecipeIngredient($recipe->getIngredient($x, $z));
} }
} }
@ -180,6 +195,7 @@ class CraftingDataPacket extends DataPacket{
$stream->put(str_repeat("\x00", 16)); //Null UUID $stream->put(str_repeat("\x00", 16)); //Null UUID
$stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks) $stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks)
$stream->putVarInt(50); //TODO: priority
return CraftingDataPacket::ENTRY_SHAPED; return CraftingDataPacket::ENTRY_SHAPED;
} }
@ -212,8 +228,9 @@ class CraftingDataPacket extends DataPacket{
$this->putUnsignedVarInt(count($this->entries)); $this->putUnsignedVarInt(count($this->entries));
$writer = new NetworkBinaryStream(); $writer = new NetworkBinaryStream();
$counter = 0;
foreach($this->entries as $d){ foreach($this->entries as $d){
$entryType = self::writeEntry($d, $writer); $entryType = self::writeEntry($d, $writer, $counter++);
if($entryType >= 0){ if($entryType >= 0){
$this->putVarInt($entryType); $this->putVarInt($entryType);
$this->put($writer->getBuffer()); $this->put($writer->getBuffer());

View File

@ -0,0 +1,145 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
use function count;
class LevelChunkPacket extends DataPacket/* implements ClientboundPacket*/{
public const NETWORK_ID = ProtocolInfo::LEVEL_CHUNK_PACKET;
/** @var int */
private $chunkX;
/** @var int */
private $chunkZ;
/** @var int */
private $subChunkCount;
/** @var bool */
private $cacheEnabled;
/** @var int[] */
private $usedBlobHashes = [];
/** @var string */
private $extraPayload;
public static function withoutCache(int $chunkX, int $chunkZ, int $subChunkCount, string $payload) : self{
$result = new self;
$result->chunkX = $chunkX;
$result->chunkZ = $chunkZ;
$result->subChunkCount = $subChunkCount;
$result->extraPayload = $payload;
$result->cacheEnabled = false;
return $result;
}
public static function withCache(int $chunkX, int $chunkZ, int $subChunkCount, array $usedBlobHashes, string $extraPayload) : self{
(static function(int ...$hashes){})($usedBlobHashes);
$result = new self;
$result->chunkX = $chunkX;
$result->chunkZ = $chunkZ;
$result->subChunkCount = $subChunkCount;
$result->extraPayload = $extraPayload;
$result->cacheEnabled = true;
$result->usedBlobHashes = $usedBlobHashes;
return $result;
}
/**
* @return int
*/
public function getChunkX() : int{
return $this->chunkX;
}
/**
* @return int
*/
public function getChunkZ() : int{
return $this->chunkZ;
}
/**
* @return int
*/
public function getSubChunkCount() : int{
return $this->subChunkCount;
}
/**
* @return bool
*/
public function isCacheEnabled() : bool{
return $this->cacheEnabled;
}
/**
* @return int[]
*/
public function getUsedBlobHashes() : array{
return $this->usedBlobHashes;
}
/**
* @return string
*/
public function getExtraPayload() : string{
return $this->extraPayload;
}
protected function decodePayload() : void{
$this->chunkX = $this->getVarInt();
$this->chunkZ = $this->getVarInt();
$this->subChunkCount = $this->getUnsignedVarInt();
$this->cacheEnabled = $this->getBool();
if($this->cacheEnabled){
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$this->usedBlobHashes[] = $this->getLLong();
}
}
$this->extraPayload = $this->getString();
}
protected function encodePayload() : void{
$this->putVarInt($this->chunkX);
$this->putVarInt($this->chunkZ);
$this->putUnsignedVarInt($this->subChunkCount);
$this->putBool($this->cacheEnabled);
if($this->cacheEnabled){
$this->putUnsignedVarInt(count($this->usedBlobHashes));
foreach($this->usedBlobHashes as $hash){
$this->putLLong($hash);
}
}
$this->putString($this->extraPayload);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleLevelChunk($this);
}
}

View File

@ -0,0 +1,74 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\nbt\NetworkLittleEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\NetworkSession;
class LevelEventGenericPacket extends DataPacket/* implements ClientboundPacket*/{
public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_GENERIC_PACKET;
/** @var int */
private $eventId;
/** @var string network-format NBT */
private $eventData;
public static function create(int $eventId, CompoundTag $data) : self{
$result = new self;
$result->eventId = $eventId;
$result->eventData = (new NetworkLittleEndianNBTStream())->write($data);
return $result;
}
/**
* @return int
*/
public function getEventId() : int{
return $this->eventId;
}
/**
* @return string
*/
public function getEventData() : string{
return $this->eventData;
}
protected function decodePayload() : void{
$this->eventId = $this->getVarInt();
$this->eventData = $this->getRemaining();
}
protected function encodePayload() : void{
$this->putVarInt($this->eventId);
$this->put($this->eventData);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleLevelEventGeneric($this);
}
}

View File

@ -292,8 +292,8 @@ class LevelSoundEventPacket extends DataPacket{
public const SOUND_STUN = 261; public const SOUND_STUN = 261;
public const SOUND_BLOCK_SWEET_BERRY_BUSH_HURT = 262; public const SOUND_BLOCK_SWEET_BERRY_BUSH_HURT = 262;
public const SOUND_BLOCK_SWEET_BERRY_BUSH_PICK = 263; public const SOUND_BLOCK_SWEET_BERRY_BUSH_PICK = 263;
public const SOUND_UI_CARTOGRAPHY_TABLE_TAKE_RESULT = 264; public const SOUND_BLOCK_CARTOGRAPHY_TABLE_USE = 264;
public const SOUND_UI_STONECUTTER_TAKE_RESULT = 265; public const SOUND_BLOCK_STONECUTTER_USE = 265;
public const SOUND_BLOCK_COMPOSTER_EMPTY = 266; public const SOUND_BLOCK_COMPOSTER_EMPTY = 266;
public const SOUND_BLOCK_COMPOSTER_FILL = 267; public const SOUND_BLOCK_COMPOSTER_FILL = 267;
public const SOUND_BLOCK_COMPOSTER_FILL_SUCCESS = 268; public const SOUND_BLOCK_COMPOSTER_FILL_SUCCESS = 268;
@ -302,7 +302,14 @@ class LevelSoundEventPacket extends DataPacket{
public const SOUND_BLOCK_BARREL_CLOSE = 271; public const SOUND_BLOCK_BARREL_CLOSE = 271;
public const SOUND_RAID_HORN = 272; public const SOUND_RAID_HORN = 272;
public const SOUND_BLOCK_LOOM_USE = 273; public const SOUND_BLOCK_LOOM_USE = 273;
public const SOUND_UNDEFINED = 274; public const SOUND_AMBIENT_IN_RAID = 274;
public const SOUND_UI_CARTOGRAPHY_TABLE_TAKE_RESULT = 275;
public const SOUND_UI_STONECUTTER_TAKE_RESULT = 276;
public const SOUND_UI_LOOM_TAKE_RESULT = 277;
public const SOUND_BLOCK_SMOKER_SMOKE = 278;
public const SOUND_BLOCK_BLASTFURNACE_FIRE_CRACKLE = 279;
public const SOUND_BLOCK_SMITHING_TABLE_USE = 280;
public const SOUND_UNDEFINED = 281;
/** @var int */ /** @var int */
public $sound; public $sound;

View File

@ -29,8 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class MoveEntityAbsolutePacket extends DataPacket{ class MoveActorAbsolutePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_ABSOLUTE_PACKET; public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET;
public const FLAG_GROUND = 0x01; public const FLAG_GROUND = 0x01;
public const FLAG_TELEPORT = 0x02; public const FLAG_TELEPORT = 0x02;
@ -67,6 +67,6 @@ class MoveEntityAbsolutePacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleMoveEntityAbsolute($this); return $session->handleMoveActorAbsolute($this);
} }
} }

View File

@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class MoveEntityDeltaPacket extends DataPacket{ class MoveActorDeltaPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_DELTA_PACKET; public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_DELTA_PACKET;
public const FLAG_HAS_X = 0x01; public const FLAG_HAS_X = 0x01;
public const FLAG_HAS_Y = 0x02; public const FLAG_HAS_Y = 0x02;
@ -103,6 +103,6 @@ class MoveEntityDeltaPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleMoveEntityDelta($this); return $session->handleMoveActorDelta($this);
} }
} }

View File

@ -45,11 +45,11 @@ class PacketPool{
static::registerPacket(new SetTimePacket()); static::registerPacket(new SetTimePacket());
static::registerPacket(new StartGamePacket()); static::registerPacket(new StartGamePacket());
static::registerPacket(new AddPlayerPacket()); static::registerPacket(new AddPlayerPacket());
static::registerPacket(new AddEntityPacket()); static::registerPacket(new AddActorPacket());
static::registerPacket(new RemoveEntityPacket()); static::registerPacket(new RemoveActorPacket());
static::registerPacket(new AddItemEntityPacket()); static::registerPacket(new AddItemActorPacket());
static::registerPacket(new TakeItemEntityPacket()); static::registerPacket(new TakeItemActorPacket());
static::registerPacket(new MoveEntityAbsolutePacket()); static::registerPacket(new MoveActorAbsolutePacket());
static::registerPacket(new MovePlayerPacket()); static::registerPacket(new MovePlayerPacket());
static::registerPacket(new RiderJumpPacket()); static::registerPacket(new RiderJumpPacket());
static::registerPacket(new UpdateBlockPacket()); static::registerPacket(new UpdateBlockPacket());
@ -58,7 +58,7 @@ class PacketPool{
static::registerPacket(new LevelSoundEventPacketV1()); static::registerPacket(new LevelSoundEventPacketV1());
static::registerPacket(new LevelEventPacket()); static::registerPacket(new LevelEventPacket());
static::registerPacket(new BlockEventPacket()); static::registerPacket(new BlockEventPacket());
static::registerPacket(new EntityEventPacket()); static::registerPacket(new ActorEventPacket());
static::registerPacket(new MobEffectPacket()); static::registerPacket(new MobEffectPacket());
static::registerPacket(new UpdateAttributesPacket()); static::registerPacket(new UpdateAttributesPacket());
static::registerPacket(new InventoryTransactionPacket()); static::registerPacket(new InventoryTransactionPacket());
@ -66,13 +66,13 @@ class PacketPool{
static::registerPacket(new MobArmorEquipmentPacket()); static::registerPacket(new MobArmorEquipmentPacket());
static::registerPacket(new InteractPacket()); static::registerPacket(new InteractPacket());
static::registerPacket(new BlockPickRequestPacket()); static::registerPacket(new BlockPickRequestPacket());
static::registerPacket(new EntityPickRequestPacket()); static::registerPacket(new ActorPickRequestPacket());
static::registerPacket(new PlayerActionPacket()); static::registerPacket(new PlayerActionPacket());
static::registerPacket(new EntityFallPacket()); static::registerPacket(new ActorFallPacket());
static::registerPacket(new HurtArmorPacket()); static::registerPacket(new HurtArmorPacket());
static::registerPacket(new SetEntityDataPacket()); static::registerPacket(new SetActorDataPacket());
static::registerPacket(new SetEntityMotionPacket()); static::registerPacket(new SetActorMotionPacket());
static::registerPacket(new SetEntityLinkPacket()); static::registerPacket(new SetActorLinkPacket());
static::registerPacket(new SetHealthPacket()); static::registerPacket(new SetHealthPacket());
static::registerPacket(new SetSpawnPositionPacket()); static::registerPacket(new SetSpawnPositionPacket());
static::registerPacket(new AnimatePacket()); static::registerPacket(new AnimatePacket());
@ -87,9 +87,9 @@ class PacketPool{
static::registerPacket(new CraftingEventPacket()); static::registerPacket(new CraftingEventPacket());
static::registerPacket(new GuiDataPickItemPacket()); static::registerPacket(new GuiDataPickItemPacket());
static::registerPacket(new AdventureSettingsPacket()); static::registerPacket(new AdventureSettingsPacket());
static::registerPacket(new BlockEntityDataPacket()); static::registerPacket(new BlockActorDataPacket());
static::registerPacket(new PlayerInputPacket()); static::registerPacket(new PlayerInputPacket());
static::registerPacket(new FullChunkDataPacket()); static::registerPacket(new LevelChunkPacket());
static::registerPacket(new SetCommandsEnabledPacket()); static::registerPacket(new SetCommandsEnabledPacket());
static::registerPacket(new SetDifficultyPacket()); static::registerPacket(new SetDifficultyPacket());
static::registerPacket(new ChangeDimensionPacket()); static::registerPacket(new ChangeDimensionPacket());
@ -142,22 +142,31 @@ class PacketPool{
static::registerPacket(new SetScorePacket()); static::registerPacket(new SetScorePacket());
static::registerPacket(new LabTablePacket()); static::registerPacket(new LabTablePacket());
static::registerPacket(new UpdateBlockSyncedPacket()); static::registerPacket(new UpdateBlockSyncedPacket());
static::registerPacket(new MoveEntityDeltaPacket()); static::registerPacket(new MoveActorDeltaPacket());
static::registerPacket(new SetScoreboardIdentityPacket()); static::registerPacket(new SetScoreboardIdentityPacket());
static::registerPacket(new SetLocalPlayerAsInitializedPacket()); static::registerPacket(new SetLocalPlayerAsInitializedPacket());
static::registerPacket(new UpdateSoftEnumPacket()); static::registerPacket(new UpdateSoftEnumPacket());
static::registerPacket(new NetworkStackLatencyPacket()); static::registerPacket(new NetworkStackLatencyPacket());
static::registerPacket(new ScriptCustomEventPacket()); static::registerPacket(new ScriptCustomEventPacket());
static::registerPacket(new SpawnParticleEffectPacket()); static::registerPacket(new SpawnParticleEffectPacket());
static::registerPacket(new AvailableEntityIdentifiersPacket()); static::registerPacket(new AvailableActorIdentifiersPacket());
static::registerPacket(new LevelSoundEventPacketV2()); static::registerPacket(new LevelSoundEventPacketV2());
static::registerPacket(new NetworkChunkPublisherUpdatePacket()); static::registerPacket(new NetworkChunkPublisherUpdatePacket());
static::registerPacket(new BiomeDefinitionListPacket()); static::registerPacket(new BiomeDefinitionListPacket());
static::registerPacket(new LevelSoundEventPacket()); static::registerPacket(new LevelSoundEventPacket());
static::registerPacket(new LevelEventGenericPacket());
static::registerPacket(new LecternUpdatePacket()); static::registerPacket(new LecternUpdatePacket());
static::registerPacket(new VideoStreamConnectPacket()); static::registerPacket(new VideoStreamConnectPacket());
static::registerPacket(new MapCreateLockedCopyPacket()); static::registerPacket(new AddEntityPacket());
static::registerPacket(new RemoveEntityPacket());
static::registerPacket(new ClientCacheStatusPacket());
static::registerPacket(new OnScreenTextureAnimationPacket()); static::registerPacket(new OnScreenTextureAnimationPacket());
static::registerPacket(new MapCreateLockedCopyPacket());
static::registerPacket(new StructureTemplateDataExportRequestPacket());
static::registerPacket(new StructureTemplateDataExportResponsePacket());
static::registerPacket(new UpdateBlockPropertiesPacket());
static::registerPacket(new ClientCacheBlobStatusPacket());
static::registerPacket(new ClientCacheMissResponsePacket());
} }
/** /**

View File

@ -56,6 +56,7 @@ class PlayerActionPacket extends DataPacket{
public const ACTION_STOP_SWIMMING = 22; public const ACTION_STOP_SWIMMING = 22;
public const ACTION_START_SPIN_ATTACK = 23; public const ACTION_START_SPIN_ATTACK = 23;
public const ACTION_STOP_SPIN_ATTACK = 24; public const ACTION_STOP_SPIN_ATTACK = 24;
public const ACTION_INTERACT_BLOCK = 25;
/** @var int */ /** @var int */
public $entityRuntimeId; public $entityRuntimeId;

View File

@ -39,15 +39,15 @@ interface ProtocolInfo{
/** /**
* Actual Minecraft: PE protocol version * Actual Minecraft: PE protocol version
*/ */
public const CURRENT_PROTOCOL = 354; public const CURRENT_PROTOCOL = 361;
/** /**
* Current Minecraft PE version reported by the server. This is usually the earliest currently supported version. * Current Minecraft PE version reported by the server. This is usually the earliest currently supported version.
*/ */
public const MINECRAFT_VERSION = 'v1.11.0'; public const MINECRAFT_VERSION = 'v1.12.0';
/** /**
* Version number sent to clients in ping responses. * Version number sent to clients in ping responses.
*/ */
public const MINECRAFT_VERSION_NETWORK = '1.11.0'; public const MINECRAFT_VERSION_NETWORK = '1.12.0';
public const LOGIN_PACKET = 0x01; public const LOGIN_PACKET = 0x01;
public const PLAY_STATUS_PACKET = 0x02; public const PLAY_STATUS_PACKET = 0x02;
@ -61,12 +61,12 @@ interface ProtocolInfo{
public const SET_TIME_PACKET = 0x0a; public const SET_TIME_PACKET = 0x0a;
public const START_GAME_PACKET = 0x0b; public const START_GAME_PACKET = 0x0b;
public const ADD_PLAYER_PACKET = 0x0c; public const ADD_PLAYER_PACKET = 0x0c;
public const ADD_ENTITY_PACKET = 0x0d; public const ADD_ACTOR_PACKET = 0x0d;
public const REMOVE_ENTITY_PACKET = 0x0e; public const REMOVE_ACTOR_PACKET = 0x0e;
public const ADD_ITEM_ENTITY_PACKET = 0x0f; public const ADD_ITEM_ACTOR_PACKET = 0x0f;
public const TAKE_ITEM_ENTITY_PACKET = 0x11; public const TAKE_ITEM_ACTOR_PACKET = 0x11;
public const MOVE_ENTITY_ABSOLUTE_PACKET = 0x12; public const MOVE_ACTOR_ABSOLUTE_PACKET = 0x12;
public const MOVE_PLAYER_PACKET = 0x13; public const MOVE_PLAYER_PACKET = 0x13;
public const RIDER_JUMP_PACKET = 0x14; public const RIDER_JUMP_PACKET = 0x14;
public const UPDATE_BLOCK_PACKET = 0x15; public const UPDATE_BLOCK_PACKET = 0x15;
@ -75,7 +75,7 @@ interface ProtocolInfo{
public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18; public const LEVEL_SOUND_EVENT_PACKET_V1 = 0x18;
public const LEVEL_EVENT_PACKET = 0x19; public const LEVEL_EVENT_PACKET = 0x19;
public const BLOCK_EVENT_PACKET = 0x1a; public const BLOCK_EVENT_PACKET = 0x1a;
public const ENTITY_EVENT_PACKET = 0x1b; public const ACTOR_EVENT_PACKET = 0x1b;
public const MOB_EFFECT_PACKET = 0x1c; public const MOB_EFFECT_PACKET = 0x1c;
public const UPDATE_ATTRIBUTES_PACKET = 0x1d; public const UPDATE_ATTRIBUTES_PACKET = 0x1d;
public const INVENTORY_TRANSACTION_PACKET = 0x1e; public const INVENTORY_TRANSACTION_PACKET = 0x1e;
@ -83,13 +83,13 @@ interface ProtocolInfo{
public const MOB_ARMOR_EQUIPMENT_PACKET = 0x20; public const MOB_ARMOR_EQUIPMENT_PACKET = 0x20;
public const INTERACT_PACKET = 0x21; public const INTERACT_PACKET = 0x21;
public const BLOCK_PICK_REQUEST_PACKET = 0x22; public const BLOCK_PICK_REQUEST_PACKET = 0x22;
public const ENTITY_PICK_REQUEST_PACKET = 0x23; public const ACTOR_PICK_REQUEST_PACKET = 0x23;
public const PLAYER_ACTION_PACKET = 0x24; public const PLAYER_ACTION_PACKET = 0x24;
public const ENTITY_FALL_PACKET = 0x25; public const ACTOR_FALL_PACKET = 0x25;
public const HURT_ARMOR_PACKET = 0x26; public const HURT_ARMOR_PACKET = 0x26;
public const SET_ENTITY_DATA_PACKET = 0x27; public const SET_ACTOR_DATA_PACKET = 0x27;
public const SET_ENTITY_MOTION_PACKET = 0x28; public const SET_ACTOR_MOTION_PACKET = 0x28;
public const SET_ENTITY_LINK_PACKET = 0x29; public const SET_ACTOR_LINK_PACKET = 0x29;
public const SET_HEALTH_PACKET = 0x2a; public const SET_HEALTH_PACKET = 0x2a;
public const SET_SPAWN_POSITION_PACKET = 0x2b; public const SET_SPAWN_POSITION_PACKET = 0x2b;
public const ANIMATE_PACKET = 0x2c; public const ANIMATE_PACKET = 0x2c;
@ -104,9 +104,9 @@ interface ProtocolInfo{
public const CRAFTING_EVENT_PACKET = 0x35; public const CRAFTING_EVENT_PACKET = 0x35;
public const GUI_DATA_PICK_ITEM_PACKET = 0x36; public const GUI_DATA_PICK_ITEM_PACKET = 0x36;
public const ADVENTURE_SETTINGS_PACKET = 0x37; public const ADVENTURE_SETTINGS_PACKET = 0x37;
public const BLOCK_ENTITY_DATA_PACKET = 0x38; public const BLOCK_ACTOR_DATA_PACKET = 0x38;
public const PLAYER_INPUT_PACKET = 0x39; public const PLAYER_INPUT_PACKET = 0x39;
public const FULL_CHUNK_DATA_PACKET = 0x3a; public const LEVEL_CHUNK_PACKET = 0x3a;
public const SET_COMMANDS_ENABLED_PACKET = 0x3b; public const SET_COMMANDS_ENABLED_PACKET = 0x3b;
public const SET_DIFFICULTY_PACKET = 0x3c; public const SET_DIFFICULTY_PACKET = 0x3c;
public const CHANGE_DIMENSION_PACKET = 0x3d; public const CHANGE_DIMENSION_PACKET = 0x3d;
@ -159,7 +159,7 @@ interface ProtocolInfo{
public const SET_SCORE_PACKET = 0x6c; public const SET_SCORE_PACKET = 0x6c;
public const LAB_TABLE_PACKET = 0x6d; public const LAB_TABLE_PACKET = 0x6d;
public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e; public const UPDATE_BLOCK_SYNCED_PACKET = 0x6e;
public const MOVE_ENTITY_DELTA_PACKET = 0x6f; public const MOVE_ACTOR_DELTA_PACKET = 0x6f;
public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70; public const SET_SCOREBOARD_IDENTITY_PACKET = 0x70;
public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71; public const SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET = 0x71;
public const UPDATE_SOFT_ENUM_PACKET = 0x72; public const UPDATE_SOFT_ENUM_PACKET = 0x72;
@ -167,14 +167,23 @@ interface ProtocolInfo{
public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75; public const SCRIPT_CUSTOM_EVENT_PACKET = 0x75;
public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76; public const SPAWN_PARTICLE_EFFECT_PACKET = 0x76;
public const AVAILABLE_ENTITY_IDENTIFIERS_PACKET = 0x77; public const AVAILABLE_ACTOR_IDENTIFIERS_PACKET = 0x77;
public const LEVEL_SOUND_EVENT_PACKET_V2 = 0x78; public const LEVEL_SOUND_EVENT_PACKET_V2 = 0x78;
public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79; public const NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET = 0x79;
public const BIOME_DEFINITION_LIST_PACKET = 0x7a; public const BIOME_DEFINITION_LIST_PACKET = 0x7a;
public const LEVEL_SOUND_EVENT_PACKET = 0x7b; public const LEVEL_SOUND_EVENT_PACKET = 0x7b;
public const LECTERN_UPDATE_PACKET = 0x7c; public const LEVEL_EVENT_GENERIC_PACKET = 0x7c;
public const VIDEO_STREAM_CONNECT_PACKET = 0x7d; public const LECTERN_UPDATE_PACKET = 0x7d;
public const MAP_CREATE_LOCKED_COPY_PACKET = 0x7e; public const VIDEO_STREAM_CONNECT_PACKET = 0x7e;
public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x7f; public const ADD_ENTITY_PACKET = 0x7f;
public const REMOVE_ENTITY_PACKET = 0x80;
public const CLIENT_CACHE_STATUS_PACKET = 0x81;
public const ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x82;
public const MAP_CREATE_LOCKED_COPY_PACKET = 0x83;
public const STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET = 0x84;
public const STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET = 0x85;
public const UPDATE_BLOCK_PROPERTIES_PACKET = 0x86;
public const CLIENT_CACHE_BLOB_STATUS_PACKET = 0x87;
public const CLIENT_CACHE_MISS_RESPONSE_PACKET = 0x88;
} }

View 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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class RemoveActorPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET;
/** @var int */
public $entityUniqueId;
protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId();
}
protected function encodePayload(){
$this->putEntityUniqueId($this->entityUniqueId);
}
public function handle(NetworkSession $session) : bool{
return $session->handleRemoveActor($this);
}
}

View File

@ -25,24 +25,36 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h> #include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class RemoveEntityPacket extends DataPacket{ class RemoveEntityPacket extends DataPacket/* implements ClientboundPacket*/{
public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET;
/** @var int */ /** @var int */
public $entityUniqueId; private $uvarint1;
protected function decodePayload(){ public static function create(int $uvarint1) : self{
$this->entityUniqueId = $this->getEntityUniqueId(); $result = new self;
$result->uvarint1 = $uvarint1;
return $result;
} }
protected function encodePayload(){ /**
$this->putEntityUniqueId($this->entityUniqueId); * @return int
*/
public function getUvarint1() : int{
return $this->uvarint1;
} }
public function handle(NetworkSession $session) : bool{ protected function decodePayload() : void{
return $session->handleRemoveEntity($this); $this->uvarint1 = $this->getUnsignedVarInt();
}
protected function encodePayload() : void{
$this->putUnsignedVarInt($this->uvarint1);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleRemoveEntity($this);
} }
} }

View File

@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\ResourcePackType;
class ResourcePackDataInfoPacket extends DataPacket{ class ResourcePackDataInfoPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET;
@ -42,6 +43,10 @@ class ResourcePackDataInfoPacket extends DataPacket{
public $compressedPackSize; public $compressedPackSize;
/** @var string */ /** @var string */
public $sha256; public $sha256;
/** @var bool */
public $isPremium = false;
/** @var int */
public $packType = ResourcePackType::RESOURCES; //TODO: check the values for this
protected function decodePayload(){ protected function decodePayload(){
$this->packId = $this->getString(); $this->packId = $this->getString();
@ -49,6 +54,8 @@ class ResourcePackDataInfoPacket extends DataPacket{
$this->chunkCount = $this->getLInt(); $this->chunkCount = $this->getLInt();
$this->compressedPackSize = $this->getLLong(); $this->compressedPackSize = $this->getLLong();
$this->sha256 = $this->getString(); $this->sha256 = $this->getString();
$this->isPremium = $this->getBool();
$this->packType = $this->getByte();
} }
protected function encodePayload(){ protected function encodePayload(){
@ -57,6 +64,8 @@ class ResourcePackDataInfoPacket extends DataPacket{
$this->putLInt($this->chunkCount); $this->putLInt($this->chunkCount);
$this->putLLong($this->compressedPackSize); $this->putLLong($this->compressedPackSize);
$this->putString($this->sha256); $this->putString($this->sha256);
$this->putBool($this->isPremium);
$this->putByte($this->packType);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

View File

@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class SetEntityDataPacket extends DataPacket{ class SetActorDataPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_DATA_PACKET; public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET;
/** @var int */ /** @var int */
public $entityRuntimeId; public $entityRuntimeId;
@ -47,6 +47,6 @@ class SetEntityDataPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleSetEntityData($this); return $session->handleSetActorData($this);
} }
} }

View File

@ -29,8 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\network\mcpe\protocol\types\EntityLink;
class SetEntityLinkPacket extends DataPacket{ class SetActorLinkPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_LINK_PACKET; public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET;
/** @var EntityLink */ /** @var EntityLink */
public $link; public $link;
@ -44,6 +44,6 @@ class SetEntityLinkPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleSetEntityLink($this); return $session->handleSetActorLink($this);
} }
} }

View File

@ -29,8 +29,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class SetEntityMotionPacket extends DataPacket{ class SetActorMotionPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::SET_ENTITY_MOTION_PACKET; public const NETWORK_ID = ProtocolInfo::SET_ACTOR_MOTION_PACKET;
/** @var int */ /** @var int */
public $entityRuntimeId; public $entityRuntimeId;
@ -48,6 +48,6 @@ class SetEntityMotionPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleSetEntityMotion($this); return $session->handleSetActorMotion($this);
} }
} }

View File

@ -61,6 +61,7 @@ class SetScorePacket extends DataPacket{
throw new \UnexpectedValueException("Unknown entry type $entry->type"); throw new \UnexpectedValueException("Unknown entry type $entry->type");
} }
} }
$this->entries[] = $entry;
} }
} }

View File

@ -32,12 +32,17 @@ use pocketmine\network\mcpe\NetworkSession;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use function count; use function count;
use function file_get_contents;
use function json_decode;
use const pocketmine\RESOURCE_PATH;
class StartGamePacket extends DataPacket{ class StartGamePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
/** @var string|null */ /** @var string|null */
private static $runtimeIdTableCache; private static $blockTableCache = null;
/** @var string|null */
private static $itemTableCache = null;
/** @var int */ /** @var int */
public $entityUniqueId; public $entityUniqueId;
@ -122,6 +127,8 @@ class StartGamePacket extends DataPacket{
public $isFromWorldTemplate = false; public $isFromWorldTemplate = false;
/** @var bool */ /** @var bool */
public $isWorldTemplateOptionLocked = false; public $isWorldTemplateOptionLocked = false;
/** @var bool */
public $onlySpawnV1Villagers = false;
/** @var string */ /** @var string */
public $levelId = ""; //base64 string, usually the same as world folder name in vanilla public $levelId = ""; //base64 string, usually the same as world folder name in vanilla
@ -138,11 +145,10 @@ class StartGamePacket extends DataPacket{
/** @var string */ /** @var string */
public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort
/** @var bool */ /** @var array|null ["name" (string), "data" (int16), "legacy_id" (int16)] */
public $onlySpawnV1Villagers = false; public $blockTable = null;
/** @var array|null string (name) => int16 (legacyID) */
/** @var array|null each entry must have a "name" (string) and "data" (int16) element */ public $itemTable = null;
public $runtimeIdTable = null;
protected function decodePayload(){ protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId(); $this->entityUniqueId = $this->getEntityUniqueId();
@ -185,6 +191,7 @@ class StartGamePacket extends DataPacket{
$this->useMsaGamertagsOnly = $this->getBool(); $this->useMsaGamertagsOnly = $this->getBool();
$this->isFromWorldTemplate = $this->getBool(); $this->isFromWorldTemplate = $this->getBool();
$this->isWorldTemplateOptionLocked = $this->getBool(); $this->isWorldTemplateOptionLocked = $this->getBool();
$this->onlySpawnV1Villagers = $this->getBool();
$this->levelId = $this->getString(); $this->levelId = $this->getString();
$this->worldName = $this->getString(); $this->worldName = $this->getString();
@ -194,18 +201,23 @@ class StartGamePacket extends DataPacket{
$this->enchantmentSeed = $this->getVarInt(); $this->enchantmentSeed = $this->getVarInt();
$count = $this->getUnsignedVarInt(); $this->blockTable = [];
$table = []; for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
for($i = 0; $i < $count; ++$i){
$id = $this->getString(); $id = $this->getString();
$data = $this->getLShort(); $data = $this->getSignedLShort();
$unknown = $this->getSignedLShort();
$table[$i] = ["name" => $id, "data" => $data]; $this->blockTable[$i] = ["name" => $id, "data" => $data, "legacy_id" => $unknown];
}
$this->itemTable = [];
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
$id = $this->getString();
$legacyId = $this->getSignedLShort();
$this->itemTable[$id] = $legacyId;
} }
$this->runtimeIdTable = $table;
$this->multiplayerCorrelationId = $this->getString(); $this->multiplayerCorrelationId = $this->getString();
$this->onlySpawnV1Villagers = $this->getBool();
} }
protected function encodePayload(){ protected function encodePayload(){
@ -249,6 +261,7 @@ class StartGamePacket extends DataPacket{
$this->putBool($this->useMsaGamertagsOnly); $this->putBool($this->useMsaGamertagsOnly);
$this->putBool($this->isFromWorldTemplate); $this->putBool($this->isFromWorldTemplate);
$this->putBool($this->isWorldTemplateOptionLocked); $this->putBool($this->isWorldTemplateOptionLocked);
$this->putBool($this->onlySpawnV1Villagers);
$this->putString($this->levelId); $this->putString($this->levelId);
$this->putString($this->worldName); $this->putString($this->worldName);
@ -258,18 +271,25 @@ class StartGamePacket extends DataPacket{
$this->putVarInt($this->enchantmentSeed); $this->putVarInt($this->enchantmentSeed);
if($this->runtimeIdTable === null){ if($this->blockTable === null){
if(self::$runtimeIdTableCache === null){ if(self::$blockTableCache === null){
//this is a really nasty hack, but it'll do for now //this is a really nasty hack, but it'll do for now
self::$runtimeIdTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates()); self::$blockTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates());
} }
$this->put(self::$runtimeIdTableCache); $this->put(self::$blockTableCache);
}else{ }else{
$this->put(self::serializeBlockTable($this->runtimeIdTable)); $this->put(self::serializeBlockTable($this->blockTable));
}
if($this->itemTable === null){
if(self::$itemTableCache === null){
self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true));
}
$this->put(self::$itemTableCache);
}else{
$this->put(self::serializeItemTable($this->itemTable));
} }
$this->putString($this->multiplayerCorrelationId); $this->putString($this->multiplayerCorrelationId);
$this->putBool($this->onlySpawnV1Villagers);
} }
private static function serializeBlockTable(array $table) : string{ private static function serializeBlockTable(array $table) : string{
@ -278,6 +298,17 @@ class StartGamePacket extends DataPacket{
foreach($table as $v){ foreach($table as $v){
$stream->putString($v["name"]); $stream->putString($v["name"]);
$stream->putLShort($v["data"]); $stream->putLShort($v["data"]);
$stream->putLShort($v["legacy_id"]);
}
return $stream->getBuffer();
}
private static function serializeItemTable(array $table) : string{
$stream = new NetworkBinaryStream();
$stream->putUnsignedVarInt(count($table));
foreach($table as $name => $legacyId){
$stream->putString($name);
$stream->putLShort($legacyId);
} }
return $stream->getBuffer(); return $stream->getBuffer();
} }

View File

@ -0,0 +1,44 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class StructureTemplateDataExportRequestPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_EXPORT_REQUEST_PACKET;
protected function decodePayload() : void{
//TODO
}
protected function encodePayload() : void{
//TODO
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleStructureTemplateDataExportRequest($this);
}
}

View File

@ -0,0 +1,44 @@
<?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\network\mcpe\protocol;
#include <rules/DataPacket.h>
use pocketmine\network\mcpe\NetworkSession;
class StructureTemplateDataExportResponsePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_EXPORT_RESPONSE_PACKET;
protected function decodePayload() : void{
//TODO
}
protected function encodePayload() : void{
//TODO
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleStructureTemplateDataExportResponse($this);
}
}

View File

@ -28,8 +28,8 @@ namespace pocketmine\network\mcpe\protocol;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class TakeItemEntityPacket extends DataPacket{ class TakeItemActorPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ENTITY_PACKET; public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET;
/** @var int */ /** @var int */
public $target; public $target;
@ -47,6 +47,6 @@ class TakeItemEntityPacket extends DataPacket{
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleTakeItemEntity($this); return $session->handleTakeItemActor($this);
} }
} }

View File

@ -37,7 +37,7 @@ class UnknownPacket extends DataPacket{
public function pid(){ public function pid(){
if(strlen($this->payload ?? "") > 0){ if(strlen($this->payload ?? "") > 0){
return ord($this->payload{0}); return ord($this->payload[0]);
} }
return self::NETWORK_ID; return self::NETWORK_ID;
} }

View File

@ -25,32 +25,31 @@ namespace pocketmine\network\mcpe\protocol;
#include <rules/DataPacket.h> #include <rules/DataPacket.h>
use pocketmine\nbt\NetworkLittleEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\NetworkSession;
class FullChunkDataPacket extends DataPacket{ class UpdateBlockPropertiesPacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::FULL_CHUNK_DATA_PACKET; public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PROPERTIES_PACKET;
/** @var int */
public $chunkX;
/** @var int */
public $chunkZ;
/** @var string */ /** @var string */
public $data; private $nbt;
protected function decodePayload(){ public static function create(CompoundTag $data) : self{
$this->chunkX = $this->getVarInt(); $result = new self;
$this->chunkZ = $this->getVarInt(); $result->nbt = (new NetworkLittleEndianNBTStream())->write($data);
$this->data = $this->getString(); return $result;
} }
protected function encodePayload(){ protected function decodePayload() : void{
$this->putVarInt($this->chunkX); $this->nbt = $this->getRemaining();
$this->putVarInt($this->chunkZ);
$this->putString($this->data);
} }
public function handle(NetworkSession $session) : bool{ protected function encodePayload() : void{
return $session->handleFullChunkData($this); $this->put($this->nbt);
}
public function handle(NetworkSession $handler) : bool{
return $handler->handleUpdateBlockProperties($this);
} }
} }

View File

@ -39,17 +39,25 @@ class VideoStreamConnectPacket extends DataPacket/* implements ClientboundPacket
public $frameSendFrequency; public $frameSendFrequency;
/** @var int */ /** @var int */
public $action; public $action;
/** @var int */
public $resolutionX;
/** @var int */
public $resolutionY;
protected function decodePayload() : void{ protected function decodePayload() : void{
$this->serverUri = $this->getString(); $this->serverUri = $this->getString();
$this->frameSendFrequency = $this->getLFloat(); $this->frameSendFrequency = $this->getLFloat();
$this->action = $this->getByte(); $this->action = $this->getByte();
$this->resolutionX = $this->getLInt();
$this->resolutionY = $this->getLInt();
} }
protected function encodePayload() : void{ protected function encodePayload() : void{
$this->putString($this->serverUri); $this->putString($this->serverUri);
$this->putLFloat($this->frameSendFrequency); $this->putLFloat($this->frameSendFrequency);
$this->putByte($this->action); $this->putByte($this->action);
$this->putLInt($this->resolutionX);
$this->putLInt($this->resolutionY);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

View File

@ -0,0 +1,56 @@
<?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\network\mcpe\protocol\types;
class ChunkCacheBlob{
/** @var int */
private $hash;
/** @var string */
private $payload;
/**
* ChunkCacheBlob constructor.
*
* @param int $hash
* @param string $payload
*/
public function __construct(int $hash, string $payload){
$this->hash = $hash;
$this->payload = $payload;
}
/**
* @return int
*/
public function getHash() : int{
return $this->hash;
}
/**
* @return string
*/
public function getPayload() : string{
return $this->payload;
}
}

View 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\network\mcpe\protocol\types;
final class ResourcePackType{
private function __construct(){
//NOOP
}
public const INVALID = 0;
public const RESOURCES = 1;
public const BEHAVIORS = 2;
public const WORLD_TEMPLATE = 3;
public const ADDON = 4; //scripts?
public const SKINS = 5;
}

View File

@ -56,9 +56,11 @@ final class RuntimeBlockMapping{
foreach($compressedTable as $prefix => $entries){ foreach($compressedTable as $prefix => $entries){
foreach($entries as $shortStringId => $states){ foreach($entries as $shortStringId => $states){
foreach($states as $state){ foreach($states as $state){
$name = "$prefix:$shortStringId";
$decompressed[] = [ $decompressed[] = [
"name" => "$prefix:$shortStringId", "name" => $name,
"data" => $state "data" => $state,
"legacy_id" => $legacyIdMap[$name]
]; ];
} }
} }
@ -66,11 +68,12 @@ final class RuntimeBlockMapping{
self::$bedrockKnownStates = self::randomizeTable($decompressed); self::$bedrockKnownStates = self::randomizeTable($decompressed);
foreach(self::$bedrockKnownStates as $k => $obj){ foreach(self::$bedrockKnownStates as $k => $obj){
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries if($obj["data"] > 15){
if(!isset($legacyIdMap[$obj["name"]])){ //TODO: in 1.12 they started using data values bigger than 4 bits which we can't handle right now
continue; continue;
} }
self::registerMapping($k, $legacyIdMap[$obj["name"]], $obj["data"]); //this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
self::registerMapping($k, $obj["legacy_id"], $obj["data"]);
} }
} }

View File

@ -92,7 +92,7 @@ class QueryHandler{
public function handle(AdvancedSourceInterface $interface, string $address, int $port, string $packet){ public function handle(AdvancedSourceInterface $interface, string $address, int $port, string $packet){
$offset = 2; $offset = 2;
$packetType = ord($packet{$offset++}); $packetType = ord($packet[$offset++]);
$sessionID = Binary::readInt(substr($packet, $offset, 4)); $sessionID = Binary::readInt(substr($packet, $offset, 4));
$offset += 4; $offset += 4;
$payload = substr($packet, $offset); $payload = substr($packet, $offset);

View File

@ -154,7 +154,7 @@ class BanList{
$fp = @fopen($this->file, "r"); $fp = @fopen($this->file, "r");
if(is_resource($fp)){ if(is_resource($fp)){
while(($line = fgets($fp)) !== false){ while(($line = fgets($fp)) !== false){
if($line{0} !== "#"){ if($line[0] !== "#"){
try{ try{
$entry = BanEntry::fromString($line); $entry = BanEntry::fromString($line);
if($entry instanceof BanEntry){ if($entry instanceof BanEntry){

View File

@ -286,7 +286,7 @@ class PluginManager{
$plugins[$name] = $file; $plugins[$name] = $file;
$softDependencies[$name] = $description->getSoftDepend(); $softDependencies[$name] = array_merge($softDependencies[$name] ?? [], $description->getSoftDepend());
$dependencies[$name] = $description->getDepend(); $dependencies[$name] = $description->getDepend();
foreach($description->getLoadBefore() as $before){ foreach($description->getLoadBefore() as $before){

View File

@ -28,7 +28,7 @@ use pocketmine\nbt\NetworkLittleEndianNBTStream;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockActorDataPacket;
use pocketmine\Player; use pocketmine\Player;
abstract class Spawnable extends Tile{ abstract class Spawnable extends Tile{
@ -37,8 +37,8 @@ abstract class Spawnable extends Tile{
/** @var NetworkLittleEndianNBTStream|null */ /** @var NetworkLittleEndianNBTStream|null */
private static $nbtWriter = null; private static $nbtWriter = null;
public function createSpawnPacket() : BlockEntityDataPacket{ public function createSpawnPacket() : BlockActorDataPacket{
$pk = new BlockEntityDataPacket(); $pk = new BlockActorDataPacket();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;

View File

@ -300,7 +300,7 @@ class MainLogger extends \AttachableThreadedLogger{
$threadName = (new \ReflectionClass($thread))->getShortName() . " thread"; $threadName = (new \ReflectionClass($thread))->getShortName() . " thread";
} }
$message = sprintf($this->format, $time->format("H:i:s"), $color, $threadName, $prefix, $message); $message = sprintf($this->format, $time->format("H:i:s"), $color, $threadName, $prefix, TextFormat::clean($message, false));
if(!Terminal::isInit()){ if(!Terminal::isInit()){
Terminal::init($this->mainThreadHasFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread Terminal::init($this->mainThreadHasFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread

View File

@ -496,7 +496,7 @@ class Utils{
public static function javaStringHash(string $string) : int{ public static function javaStringHash(string $string) : int{
$hash = 0; $hash = 0;
for($i = 0, $len = strlen($string); $i < $len; $i++){ for($i = 0, $len = strlen($string); $i < $len; $i++){
$ord = ord($string{$i}); $ord = ord($string[$i]);
if($ord & 0x80){ if($ord & 0x80){
$ord -= 0x100; $ord -= 0x100;
} }