pmmp / PocketMine-MP

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

Block cache corruption when modifying results of `getBlock()` #2770

Open dktapps opened 5 years ago

dktapps commented 5 years ago

Issue description

Blocks are cached at the world level to improve performance of accesses. This is problematic because getBlock() does not clone or remove blocks from the cache, so if they are modified without setting them back into the world, the block cache becomes corrupted.

This has been seen in the past when plugin devs modify the meta values of things like wool expecting to see a different colour - it sort-of works if you click on it totrigger block updates, but the changes don't save.

Steps to reproduce the issue

  1. Fetch a block from the world, such as wool.
  2. Alter its properties in some way, for example changing its meta value.
  3. Don't setBlock().
  4. Click the block in game and notice the block appears to have updated to reflect your change.
  5. Quit the game and rejoin and notice nothing is there.

OS and versions

dktapps commented 3 years ago

This could be solved by implementing a BlockCacheRecord which records the fullID of the block, alongside the block object that's supposed to represent it. If the block object's fullID doesn't match the recorded ID, we throw it away and get a new one from BlockFactory. However, this would come at a minor performance cost.