pmmp / PocketMine-MP

A server software for Minecraft: Bedrock Edition in PHP
https://pmmp.io
GNU Lesser General Public License v3.0
3.26k stars 1.54k forks source link

ItemEntity failed to load when loading vanilla world #5063

Closed alvin0319 closed 2 years ago

alvin0319 commented 2 years ago

Issue description

While working on #4690, I noticed that ItemEntity fails to load from the disk.

Steps to reproduce the issue

  1. Set up a modern-world-support branch.
  2. Get a fresh vanilla world, which has ItemEntity spawned. The world that I used is provided below.
  3. Load world.

OS and versions

Crashdump, backtrace or other files

World: world.zip

[21:10:32.455] [Server thread/ERROR]: [World: My World] [Loading chunk 28 -3] Bad entity data at list position 0: Item is invalid
[21:10:32.456] [Server thread/CRITICAL]: pocketmine\data\SavedDataLoadingException: "Item is invalid" (EXCEPTION) in "pmsrc/src/entity/EntityFactory" at line 125
--- Stack trace ---
  #0 pmsrc/src/entity/EntityFactory(243): pocketmine\entity\EntityFactory->pocketmine\entity\{closure}(object pocketmine\world\World#25029, object pocketmine\nbt\tag\CompoundTag#58051)
  #1 pmsrc/src/world/World(2488): pocketmine\entity\EntityFactory->createFromData(object pocketmine\world\World#25029, object pocketmine\nbt\tag\CompoundTag#58051)
  #2 pmsrc/src/world/World(2443): pocketmine\world\World->initChunk(int 28, int -3, object pocketmine\world\format\io\ChunkData#59661)
  #3 pmsrc/src/world/World(665): pocketmine\world\World->loadChunk(int 28, int -3)
  #4 pmsrc/src/player/Player(761): pocketmine\world\World->registerChunkLoader(object pocketmine\player\PlayerChunkLoader#29325, int 28, int -3, true)
  #5 pmsrc/src/player/Player(928): pocketmine\player\Player->requestChunks()
  #6 pmsrc/src/network/mcpe/NetworkSession(1054): pocketmine\player\Player->doChunkRequests()
  #7 pmsrc/src/network/NetworkSessionManager(67): pocketmine\network\mcpe\NetworkSession->tick()
  #8 pmsrc/src/network/Network(88): pocketmine\network\NetworkSessionManager->tick()
  #9 pmsrc/src/Server(1814): pocketmine\network\Network->tick()
  #10 pmsrc/src/Server(1693): pocketmine\Server->tick()
  #11 pmsrc/src/Server(1063): pocketmine\Server->tickProcessor()
  #12 pmsrc/src/PocketMine(304): pocketmine\Server->__construct(object BaseClassLoader#2, object pocketmine\utils\MainLogger#3, string[65] D:\D-Backups\MCBE\PocketMine-MP-Projects\PocketMine-MP-workspace\, string[73] D:\D-Backups\MCBE\PocketMine-MP-Projects\PocketMine-MP-workspace\plugins\)
  #13 pmsrc/src/PocketMine(327): pocketmine\server()
--- End of exception information ---

When I dumped item NBT, it seemed the vanilla client used StringTag(Name) instead of IntTag(id).

Here is the item NBT that I dumped:

object(pocketmine\nbt\tag\CompoundTag)#58128 (2) {
  ["value":"pocketmine\nbt\tag\CompoundTag":private]=>
  array(4) {
    ["Count"]=>
    object(pocketmine\nbt\tag\ByteTag)#58150 (2) {
      ["cloning":protected]=>
      bool(false)
      ["value":"pocketmine\nbt\tag\ByteTag":private]=>
      int(1)
    }
    ["Damage"]=>
    object(pocketmine\nbt\tag\ShortTag)#58152 (2) {
      ["cloning":protected]=>
      bool(false)
      ["value":"pocketmine\nbt\tag\ShortTag":private]=>
      int(0)
    }
    ["Name"]=>
    object(pocketmine\nbt\tag\StringTag)#58154 (2) {
      ["value":"pocketmine\nbt\tag\StringTag":private]=>
      string(22) "minecraft:glow_ink_sac"
      ["cloning":protected]=>
      bool(false)
    }
    ["WasPickedUp"]=>
    object(pocketmine\nbt\tag\ByteTag)#58141 (2) {
      ["cloning":protected]=>
      bool(false)
      ["value":"pocketmine\nbt\tag\ByteTag":private]=>
      int(0)
    }
  }
  ["cloning":protected]=>
  bool(false)
}

A possible solution seems to be to find StringTag(Name) in Item::nbtDeserialize() and parse it from LegacyStringToItemParser.

https://github.com/pmmp/PocketMine-MP/blob/2ec65ba799c0d0f2ed593cd598ae7f9b32572faa/src/item/Item.php#L680

dktapps commented 2 years ago

This is a known issue and is already being worked on.