Code Monkey home page Code Monkey logo

nbt's Introduction

PocketMine-NBT

CI

PHP library for working with the NBT (Named Binary Tag) data storage format, as designed by Mojang.

nbt's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nbt's Issues

Better handling of duplicate CompoundTag keys

Currently, a duplicate key appearing anywhere in some NBT data tree will cause the entire tree to be undecodable using this library. This is severely problematic for legacy PM worlds, because the entire chunk is stored as one big NBT blob in MCRegion, Anvil and PMAnvil worlds. This means that any appearance of a duplicated key will cause the entire chunk to be discarded as corrupted.

This issue has caused a large number of worlds created with PM older than ~2017 to lose any chunks containing furnace due to a duplicate BurnTime key (this was originally fixed by pmmp/PocketMine-MP@20b86bd). However, any worlds created before this commit which were not loaded prior to the fix of #54 will now experience full data loss if this happened in any of their chunks, which is not cool.

Possible solutions

  • Go back to the old way, and don't throw errors on duplicate tags - simply allow the last tag with the same name to overwrite the earlier ones - not perfect; someone else like me may consider this a bug in the future and then add a new check and cause the same problem.
  • Keep a list of tags under each name in a compound. This would avoid any loss of data, but would increase implementation complexity for minimal benefit.
  • Accept a user-provided callback to decide what to do.
  • Accept flags to decide what should be done (e.g. NbtSerializer::IGNORE_DUPLICATE_COMPOUND_KEYS).

Root tag may not be a Compound

On the master branch (targeted for 0.3) the API has been changed to assume that the root tag of a valid NBT tree should always be a CompoundTag. However, recent developments in Bedrock 1.13 have shown us that this assumption is false, despite what is written in the original NBT specification.

It's now possible to get a ListTag as root (see, for example, the StartGamePacket block palette), and possibly other tags too.

Add recursion protection for cloning

If a tag is set as a child of itself (directly or indirectly) and then later cloned, the application will crash due to infinite recursion. Instead, this proposes that recursive dependencies should be detected when cloning a tag, and an exception be thrown when a recursive dependency is detected.

NBTStream::fromArray() is broken

Stack trace:

[19:02:11] [Server thread/CRITICAL]: RuntimeException: "Cannot access dynamic field "Pos": Dynamic field access on pocketmine\nbt\tag\CompoundTag is no longer supported" (EXCEPTION) in "vendor/pocketmine/nbt/src/tag/NoDynamicFieldsTrait" at line 31
[19:02:11] [Server thread/DEBUG]: #0 vendor/pocketmine/nbt/src/tag/NoDynamicFieldsTrait(35): pocketmine\nbt\tag\CompoundTag->throw(string[3] Pos)
[19:02:11] [Server thread/DEBUG]: #1 vendor/pocketmine/nbt/src/NBTStream(344): pocketmine\nbt\tag\CompoundTag->__get(string[3] Pos)
[19:02:11] [Server thread/DEBUG]: #2 vendor/pocketmine/nbt/src/NBTStream(362): pocketmine\nbt\NBTStream::tagFromArray(object pocketmine\nbt\tag\CompoundTag, array[15], array[2])
[19:02:11] [Server thread/DEBUG]: #3 plugins/WEdit/src/jp/mcbe/WEdit/task/PasteTask(130): pocketmine\nbt\NBTStream::fromArray(array[15])

Code:

$nbtArray = NBTStream::toArray($entity->namedtag);
$entityNBT = NBTStream::fromArray($nbtArray);

Primitive tags can be considered immutable

Since the separation of tag names from tags themselves, most Tag descendents now happen to have immutable state. We can take advantage of this during cloning by not cloning primitive tags when deep-cloning things like CompoundTags.

CompoundTag bug

So, my server somewhat lags upon certain items. And sometimes causes a player to get kicked from the server for flying when they wern't even flying. This is the error I'm getting at the same time:

TypeError: "Return value of pocketmine\nbt\tag\CompoundTag::key() must be of the type string or null, integer returned" (EXCEPTION) in "vendor/pocketmine/nbt/src/tag/CompoundTag" at line 474
04.09 10:09:52 [Server] Server thread/DEBUG #0 vendor/pocketmine/nbt/src/tag/CompoundTag(493): pocketmine\nbt\tag\CompoundTag->key()
04.09 10:09:52 [Server] Server thread/DEBUG #1 vendor/pocketmine/nbt/src/tag/NamedTag(106): pocketmine\nbt\tag\CompoundTag->equalsValue(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:52 [Server] Server thread/DEBUG #2 src/pocketmine/item/Item(835): pocketmine\nbt\tag\NamedTag->equals(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:52 [Server] Server thread/DEBUG #3 src/pocketmine/Player(2640): pocketmine\item\Item->equals(pocketmine\item\ItemBlock object)
04.09 10:09:52 [Server] Server thread/DEBUG #4 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(136): pocketmine\Player->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #5 src/pocketmine/network/mcpe/protocol/MobEquipmentPacket(63): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #6 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\MobEquipmentPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:52 [Server] Server thread/DEBUG #7 src/pocketmine/network/mcpe/protocol/BatchPacket(114): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #8 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\BatchPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:52 [Server] Server thread/DEBUG #9 src/pocketmine/Player(3056): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #10 src/pocketmine/network/mcpe/RakLibInterface(162): pocketmine\Player->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #11 vendor/pocketmine/raklib/src/server/ServerHandler(98): pocketmine\network\mcpe\RakLibInterface->handleEncapsulated(string 82.38.148.87 60663, raklib\protocol\EncapsulatedPacket object, integer 0)
04.09 10:09:52 [Server] Server thread/DEBUG #12 src/pocketmine/network/mcpe/RakLibInterface(103): raklib\server\ServerHandler->handlePacket()
04.09 10:09:52 [Server] Server thread/DEBUG #13 src/pocketmine/network/Network(94): pocketmine\network\mcpe\RakLibInterface->process()
04.09 10:09:52 [Server] Server thread/DEBUG #14 src/pocketmine/network/mcpe/RakLibInterface(80): pocketmine\network\Network->processInterface(pocketmine\network\mcpe\RakLibInterface object)
04.09 10:09:52 [Server] Server thread/DEBUG #15 vendor/pocketmine/snooze/src/SleeperHandler(120): pocketmine\network\mcpe\RakLibInterface->pocketmine\network\mcpe\{closure}()
04.09 10:09:52 [Server] Server thread/DEBUG #16 vendor/pocketmine/snooze/src/SleeperHandler(82): pocketmine\snooze\SleeperHandler->processNotifications()
04.09 10:09:52 [Server] Server thread/DEBUG #17 src/pocketmine/Server(2259): pocketmine\snooze\SleeperHandler->sleepUntil(double 1536055792.0863)
04.09 10:09:52 [Server] Server thread/DEBUG #18 src/pocketmine/Server(2134): pocketmine\Server->tickProcessor()
04.09 10:09:52 [Server] Server thread/DEBUG #19 src/pocketmine/Server(1700): pocketmine\Server->start()
04.09 10:09:52 [Server] Server thread/DEBUG #20 src/pocketmine/PocketMine(243): pocketmine\Server->__construct(BaseClassLoader object, pocketmine\utils\MainLogger object, string /, string /plugins/)
04.09 10:09:52 [Server] Server thread/DEBUG #21 /custom-php7.2.phar(1): require(string phar:///custom-php7.2.phar/src/pocketmine/PocketMine.php)
04.09 10:09:52 [Server] RakLibServer thread/NOTICE Blocked 82.38.148.87 for 5 seconds
04.09 10:09:57 [Server] Server thread/CRITICAL TypeError: "Return value of pocketmine\nbt\tag\CompoundTag::key() must be of the type string or null, integer returned" (EXCEPTION) in "vendor/pocketmine/nbt/src/tag/CompoundTag" at line 474
04.09 10:09:57 [Server] Server thread/DEBUG #0 vendor/pocketmine/nbt/src/tag/CompoundTag(493): pocketmine\nbt\tag\CompoundTag->key()
04.09 10:09:57 [Server] Server thread/DEBUG #1 vendor/pocketmine/nbt/src/tag/NamedTag(106): pocketmine\nbt\tag\CompoundTag->equalsValue(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:57 [Server] Server thread/DEBUG #2 src/pocketmine/item/Item(835): pocketmine\nbt\tag\NamedTag->equals(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:57 [Server] Server thread/DEBUG #3 src/pocketmine/Player(2640): pocketmine\item\Item->equals(pocketmine\item\ItemBlock object)
04.09 10:09:57 [Server] Server thread/DEBUG #4 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(136): pocketmine\Player->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #5 src/pocketmine/network/mcpe/protocol/MobEquipmentPacket(63): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #6 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\MobEquipmentPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:57 [Server] Server thread/DEBUG #7 src/pocketmine/network/mcpe/protocol/BatchPacket(114): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #8 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\BatchPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:57 [Server] Server thread/DEBUG #9 src/pocketmine/Player(3056): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #10 src/pocketmine/network/mcpe/RakLibInterface(162): pocketmine\Player->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #11 vendor/pocketmine/raklib/src/server/ServerHandler(98): pocketmine\network\mcpe\RakLibInterface->handleEncapsulated(string 82.38.148.87 60663, raklib\protocol\EncapsulatedPacket object, integer 0)
04.09 10:09:57 [Server] Server thread/DEBUG #12 src/pocketmine/network/mcpe/RakLibInterface(103): raklib\server\ServerHandler->handlePacket()
04.09 10:09:57 [Server] Server thread/DEBUG #13 src/pocketmine/network/Network(94): pocketmine\network\mcpe\RakLibInterface->process()
04.09 10:09:57 [Server] Server thread/DEBUG #14 src/pocketmine/network/mcpe/RakLibInterface(80): pocketmine\network\Network->processInterface(pocketmine\network\mcpe\RakLibInterface object)
04.09 10:09:57 [Server] Server thread/DEBUG #15 vendor/pocketmine/snooze/src/SleeperHandler(120): pocketmine\network\mcpe\RakLibInterface->pocketmine\network\mcpe\{closure}()
04.09 10:09:57 [Server] Server thread/DEBUG #16 vendor/pocketmine/snooze/src/SleeperHandler(82): pocketmine\snooze\SleeperHandler->processNotifications()
04.09 10:09:57 [Server] Server thread/DEBUG #17 src/pocketmine/Server(2259): pocketmine\snooze\SleeperHandler->sleepUntil(double 1536055797.5863)
04.09 10:09:57 [Server] Server thread/DEBUG #18 src/pocketmine/Server(2134): pocketmine\Server->tickProcessor()
04.09 10:09:57 [Server] Server thread/DEBUG #19 src/pocketmine/Server(1700): pocketmine\Server->start()
04.09 10:09:57 [Server] Server thread/DEBUG #20 src/pocketmine/PocketMine(243): pocketmine\Server->__construct(BaseClassLoader object, pocketmine\utils\MainLogger object, string /, string /plugins/)
04.09 10:09:57 [Server] Server thread/DEBUG #21 /custom-php7.2.phar(1): require(string phar:///custom-php7.2.phar/src/pocketmine/PocketMine.php)

Steps to reproduce the issue
... Place an item (MobSpawner)
... After a couple of seconds, it lags back, and despawns.
Keep jump running, and that kicks you for flying (As if the server lagged), but on my other server, it works fine).
Server version: PocketMine-MP 3.2.0 for Minecraft: Bedrock Edition v1.6.0 (protocol version 282)
Plugins
Test on a clean server without plugins: is the issue reproducible without any plugins loaded?
Yes.
If the issue is not reproducible without plugins:
Have you asked for help on our forums before creating an issue?
Can you provide sample, minimal reproducing code for the issue? If so, paste it in the bottom section
Paste your list of plugins here (use the 'plugins' command in PocketMine-MP)
I have 0 plugins to test this issue out.

Write unit tests

incomplete list of things that should be tested:

  • CompoundTag/ListTag API
    • iterating in foreach
    • getValue()
    • getters and setters
    • array-access API (yuck)
    • count()ing tags (even things as simple as that can be botched, see da884fe)
    • tag[] = value syntax should not be allowed (CompoundTags are effectively maps)
  • ListTag-only API
    • push(), pop(), etc (once #33 is done)
    • automatic detection of tag type when list is of type TAG_End
    • assigning wrong tag type to list that is not of type TAG_End (should throw exception)
    • setting tag type manually (should only be allowed when list is empty)
    • appending tags using list[] = tag syntax
    • type checking for adding new tags to lists
    • list[] = primitiveValue should throw exceptions
  • General NamedTag API
    • bounds checking for byte/short/int/long
    • setName()/getName()
    • creating tags with and without preset values

This does not currently cover any of the streams API (TODO).

Change CompoundTag getters and setters to assert instead of throwing exceptions

In production, it is undesirable for the server to crash due to bad save data. In the case of CompoundTag->get*() these methods should instead trip an assert on finding the wrong tag type. In production (with asserts disabled) this would then simply return the default tag value quietly. The same should apply to setter methods on CompoundTag - they should just overwrite directly without triggering exceptions.

This will remove the need for additional $force parameters and similar.

This issue was raised because most plugin developers will likely just use the force mode anyway, to avoid potential crashes in production. Instead, it would be better to trigger an assert in debug mode only so that production code can just work.

Numerical CompoundTag keys converted to ints

Due to the wonderful nature of PHP arrays, numerical CompoundTag keys are converted to ints when set as array key, resulting in a crash when writing the key to a stream.

Creating a compound tag and setting a value to it, for example using CompoundTag->setInt("0", 0) results in PHP converting the "0" to 0 when set as array key, which then crashes when written here. A possible solution would be to cast value to a string.

No length restrictions for TAG_String

There is currently no length checking for StringTags. If data longer than 32767 bytes is assigned, it will be corrupted when encoded.

Additionally the length of a TAG_String is (according to the wiki) "TAG_Short's payload length, then a UTF-8 string with size length.", which means that the length is signed (hence the 32767 limit) but this library reads the length as an unsigned short (although shouldn't make any difference because correct implementations will simply have a smaller range than this library does).

Add support for TAG_LongArray

This will be needed for 1.13 world saves.

This is identical to IntArray but with 8 bytes per member instead of 4.

Excess use of NBT slows everything down

Issue description

The NBT library is extremely slow. For example, reading player data on login contributes ~25ms on player login. Player logins as a whole are extremely slow, and this contributes ~50% of the lag on login processing (~50ms on my machine).

This is nothing to do with disk reading or decompression either. I did some timing of player data reading and gained the below results:

  • Disk read: 0.1ms
  • zlib decompress: 0.2ms
  • Read NBT and create NBT object tree: ~22ms

OS and versions

  • PocketMine-MP: dda8c6cc8f04d917688d003ebe6c4b2b62cd94af
  • PHP: 7.0.16
  • Server OS: w10
  • Game version: irrelevant

Detect duplicated keys on `CompoundTag` deserialization

While no sane implementation should allow this, there is a possibility in the CompoundTag binary format for the same key to appear multiple times. If this occurs, the last tag will overwrite the previous ones, or potentially crash due to mismatched type.

This should be detected as data corruption and exceptions thrown appropriately instead.

Infinite recursion possible during encoding

If recursive references appear in NBT trees, the encoder will loop until either it segfaults or the process runs out of memory. Recursive references should be detected to prevent this problem.

Add a serializer flag to force ordering of TAG_Compound keys

It may be desirable to keep an encoded binary cache of an NBT tree, to be able to do fast bytewise comparison (such comparisons are vectorizable, and as such, considerably faster than making many thousands of equals() method calls).

However, this is currently not a reliable method of comparison, since TAG_Compounds with the same contents can have said contents ordered differently. This doesn't affect the usability of the data in the end, but it does mean that the binary representation would be different.

Use case: I want to have a fast way to compare itemstack NBT when checking item equivalence.

Separate concerns of NamedTag and tag values

Effectively, StringTag, IntTag, CompoundTag etc, are actually just tag values. They do not need to have names.

Case in point - ListTag members. ListTag members do not have names - ListTags are just a list of values.

This proposes a separation of NamedTag and Tag such that NamedTag becomes a container which encapsulates a Tag, instead of all Tags being descendent from NamedTag.

Ban serialization of Tag objects

Far too often I've seen users who serialize() internal data (like item NBT) in order to store it. This is not only stupid (because it defeats the entire point of using NBT), it's also prone to breakages like this.

This issue proposes disallowing serialization of Tag object trees, or possibly to encode them in a non-breakable format using Serializable.

Encoded NBT is always supposed to be inside a CompoundTag

Currently NBTStream->read() returns CompoundTag|NamedTag[]. However, according to the NBT specification written by Notch, an NBT blob should always be contained within a root CompoundTag.

In cases where there is multiple CompoundTags, these should be treated as a stream of separate NBT blobs, since they aren't a coherent whole.

NBTStream could be improved by breaking it up into readers and writers, where a StreamReader and StreamWriter interface is accepted to read from or write to.

Account for potential overflow of various tags

The maximum possible size of a TAG_ByteArray's payload is 2GiB, but this is not currently capped by the library. While this is a less immediate problem than the old StringTag bug, this also needs to be catered for.

This is also a problem for TAG_List and TAG_IntArray since this uses a 4-byte integer prefix to store length as well.

CompoundTag bug.

Issue description

So, my server somewhat lags upon certain items. And sometimes causes a player to get kicked from the server for flying when they wern't even flying. This is the error I'm getting at the same time:

TypeError: "Return value of pocketmine\nbt\tag\CompoundTag::key() must be of the type string or null, integer returned" (EXCEPTION) in "vendor/pocketmine/nbt/src/tag/CompoundTag" at line 474
04.09 10:09:52 [Server] Server thread/DEBUG #0 vendor/pocketmine/nbt/src/tag/CompoundTag(493): pocketmine\nbt\tag\CompoundTag->key()
04.09 10:09:52 [Server] Server thread/DEBUG #1 vendor/pocketmine/nbt/src/tag/NamedTag(106): pocketmine\nbt\tag\CompoundTag->equalsValue(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:52 [Server] Server thread/DEBUG #2 src/pocketmine/item/Item(835): pocketmine\nbt\tag\NamedTag->equals(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:52 [Server] Server thread/DEBUG #3 src/pocketmine/Player(2640): pocketmine\item\Item->equals(pocketmine\item\ItemBlock object)
04.09 10:09:52 [Server] Server thread/DEBUG #4 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(136): pocketmine\Player->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #5 src/pocketmine/network/mcpe/protocol/MobEquipmentPacket(63): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #6 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\MobEquipmentPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:52 [Server] Server thread/DEBUG #7 src/pocketmine/network/mcpe/protocol/BatchPacket(114): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #8 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\BatchPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:52 [Server] Server thread/DEBUG #9 src/pocketmine/Player(3056): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #10 src/pocketmine/network/mcpe/RakLibInterface(162): pocketmine\Player->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:52 [Server] Server thread/DEBUG #11 vendor/pocketmine/raklib/src/server/ServerHandler(98): pocketmine\network\mcpe\RakLibInterface->handleEncapsulated(string 82.38.148.87 60663, raklib\protocol\EncapsulatedPacket object, integer 0)
04.09 10:09:52 [Server] Server thread/DEBUG #12 src/pocketmine/network/mcpe/RakLibInterface(103): raklib\server\ServerHandler->handlePacket()
04.09 10:09:52 [Server] Server thread/DEBUG #13 src/pocketmine/network/Network(94): pocketmine\network\mcpe\RakLibInterface->process()
04.09 10:09:52 [Server] Server thread/DEBUG #14 src/pocketmine/network/mcpe/RakLibInterface(80): pocketmine\network\Network->processInterface(pocketmine\network\mcpe\RakLibInterface object)
04.09 10:09:52 [Server] Server thread/DEBUG #15 vendor/pocketmine/snooze/src/SleeperHandler(120): pocketmine\network\mcpe\RakLibInterface->pocketmine\network\mcpe\{closure}()
04.09 10:09:52 [Server] Server thread/DEBUG #16 vendor/pocketmine/snooze/src/SleeperHandler(82): pocketmine\snooze\SleeperHandler->processNotifications()
04.09 10:09:52 [Server] Server thread/DEBUG #17 src/pocketmine/Server(2259): pocketmine\snooze\SleeperHandler->sleepUntil(double 1536055792.0863)
04.09 10:09:52 [Server] Server thread/DEBUG #18 src/pocketmine/Server(2134): pocketmine\Server->tickProcessor()
04.09 10:09:52 [Server] Server thread/DEBUG #19 src/pocketmine/Server(1700): pocketmine\Server->start()
04.09 10:09:52 [Server] Server thread/DEBUG #20 src/pocketmine/PocketMine(243): pocketmine\Server->__construct(BaseClassLoader object, pocketmine\utils\MainLogger object, string /, string /plugins/)
04.09 10:09:52 [Server] Server thread/DEBUG #21 /custom-php7.2.phar(1): require(string phar:///custom-php7.2.phar/src/pocketmine/PocketMine.php)
04.09 10:09:52 [Server] RakLibServer thread/NOTICE Blocked 82.38.148.87 for 5 seconds
04.09 10:09:57 [Server] Server thread/CRITICAL TypeError: "Return value of pocketmine\nbt\tag\CompoundTag::key() must be of the type string or null, integer returned" (EXCEPTION) in "vendor/pocketmine/nbt/src/tag/CompoundTag" at line 474
04.09 10:09:57 [Server] Server thread/DEBUG #0 vendor/pocketmine/nbt/src/tag/CompoundTag(493): pocketmine\nbt\tag\CompoundTag->key()
04.09 10:09:57 [Server] Server thread/DEBUG #1 vendor/pocketmine/nbt/src/tag/NamedTag(106): pocketmine\nbt\tag\CompoundTag->equalsValue(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:57 [Server] Server thread/DEBUG #2 src/pocketmine/item/Item(835): pocketmine\nbt\tag\NamedTag->equals(pocketmine\nbt\tag\CompoundTag object)
04.09 10:09:57 [Server] Server thread/DEBUG #3 src/pocketmine/Player(2640): pocketmine\item\Item->equals(pocketmine\item\ItemBlock object)
04.09 10:09:57 [Server] Server thread/DEBUG #4 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(136): pocketmine\Player->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #5 src/pocketmine/network/mcpe/protocol/MobEquipmentPacket(63): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleMobEquipment(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #6 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\MobEquipmentPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:57 [Server] Server thread/DEBUG #7 src/pocketmine/network/mcpe/protocol/BatchPacket(114): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\MobEquipmentPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #8 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter(92): pocketmine\network\mcpe\protocol\BatchPacket->handle(pocketmine\network\mcpe\PlayerNetworkSessionAdapter object)
04.09 10:09:57 [Server] Server thread/DEBUG #9 src/pocketmine/Player(3056): pocketmine\network\mcpe\PlayerNetworkSessionAdapter->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #10 src/pocketmine/network/mcpe/RakLibInterface(162): pocketmine\Player->handleDataPacket(pocketmine\network\mcpe\protocol\BatchPacket object)
04.09 10:09:57 [Server] Server thread/DEBUG #11 vendor/pocketmine/raklib/src/server/ServerHandler(98): pocketmine\network\mcpe\RakLibInterface->handleEncapsulated(string 82.38.148.87 60663, raklib\protocol\EncapsulatedPacket object, integer 0)
04.09 10:09:57 [Server] Server thread/DEBUG #12 src/pocketmine/network/mcpe/RakLibInterface(103): raklib\server\ServerHandler->handlePacket()
04.09 10:09:57 [Server] Server thread/DEBUG #13 src/pocketmine/network/Network(94): pocketmine\network\mcpe\RakLibInterface->process()
04.09 10:09:57 [Server] Server thread/DEBUG #14 src/pocketmine/network/mcpe/RakLibInterface(80): pocketmine\network\Network->processInterface(pocketmine\network\mcpe\RakLibInterface object)
04.09 10:09:57 [Server] Server thread/DEBUG #15 vendor/pocketmine/snooze/src/SleeperHandler(120): pocketmine\network\mcpe\RakLibInterface->pocketmine\network\mcpe\{closure}()
04.09 10:09:57 [Server] Server thread/DEBUG #16 vendor/pocketmine/snooze/src/SleeperHandler(82): pocketmine\snooze\SleeperHandler->processNotifications()
04.09 10:09:57 [Server] Server thread/DEBUG #17 src/pocketmine/Server(2259): pocketmine\snooze\SleeperHandler->sleepUntil(double 1536055797.5863)
04.09 10:09:57 [Server] Server thread/DEBUG #18 src/pocketmine/Server(2134): pocketmine\Server->tickProcessor()
04.09 10:09:57 [Server] Server thread/DEBUG #19 src/pocketmine/Server(1700): pocketmine\Server->start()
04.09 10:09:57 [Server] Server thread/DEBUG #20 src/pocketmine/PocketMine(243): pocketmine\Server->__construct(BaseClassLoader object, pocketmine\utils\MainLogger object, string /, string /plugins/)
04.09 10:09:57 [Server] Server thread/DEBUG #21 /custom-php7.2.phar(1): require(string phar:///custom-php7.2.phar/src/pocketmine/PocketMine.php)
  • Expected result: What were you expecting to happen? For the server NOT TO lag, and be able to not get kicked for flying.
  • Actual result: What actually happened?
    The server kicks the player for flying, and items lag. (I've tried this on my second server with the same plugins, and that server seems to be fine), so not sure if it's the host, or the server.

Steps to reproduce the issue

  1. ... Place an item (MobSpawner)
  2. ... After a couple of seconds, it lags back, and despawns.
  3. Keep jump running, and that kicks you for flying (As if the server lagged), but on my other server, it works fine).

OS and versions

  • PocketMine-MP:
  • PHP: 7.2
  • Server OS: PocketMine-MP 3.2.0 for Minecraft: Bedrock Edition v1.6.0 (protocol version 282)
  • Game version: PE/Win10 (delete as appropriate)

Plugins

  • Test on a clean server without plugins: is the issue reproducible without any plugins loaded?
    Yes.
    If the issue is not reproducible without plugins:
  • Have you asked for help on our forums before creating an issue?
  • Can you provide sample, minimal reproducing code for the issue? If so, paste it in the bottom section
  • Paste your list of plugins here (use the 'plugins' command in PocketMine-MP)
    I have 0 plugins to test this issue out.

Crashdump, backtrace or other files

  • Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here.
  • Please use gist or anything else to add other files and add links here
  • ...

Make Tag->getTypeName() public

This was originally added as protected when the new toString() format was implemented. However, it would be useful for third party implementations (in PM it would be mainly useful for error reporting).

Implement deserializer cache for readonly tag types and TAG_Compound keys

During deserialization of complex NBT, we're likely to encounter NBT with many repeated values which could be cached.

For example, when deserializing a block palette file, the following types of tags are predominantly used:

  • TAG_Byte (used for true or false)
  • TAG_Int (commonly used for a small range)
  • TAG_String (commonly used for small enums)

Particularly in this case (since block state permutations are extremely repetetive) it could offer a significant memory usage advantage (and possibly performance) to keep a temporary lookup table of tag types and their values, so that the same Tag objects can be reused in different places.

For example, deserializing the current block palette (1.19.0) results in:

Type Count (without deduplicating) Count (with deduplicating)
TAG_String 18191 150
TAG_Int 3585 64
TAG_Byte 7168 2

This results in a considerable memory usage saving (16 MB -> 11 MB).

In addition, deduplication of TAG_Compound keys may also save a considerable amount of memory for complex NBT trees, due to frequently repeated keys.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.