From 58a52749ee43c343fae416c8436c2e714f7df687 Mon Sep 17 00:00:00 2001 From: kostamax27 Date: Sat, 7 Feb 2026 17:22:26 +0300 Subject: [PATCH] 0.0.4 :cry: --- README.md | 17 ++++---- src/cosmicpe/blockdata/BlockDataFactory.php | 19 ++++++--- .../blockdata/world/BlockDataChunk.php | 17 ++++---- .../blockdata/world/BlockDataWorld.php | 39 ++++++++++--------- .../world/BlockDataWorldListener.php | 6 +-- .../blockdata/world/BlockDataWorldManager.php | 21 +++++----- virion.yml | 2 +- 7 files changed, 60 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 107c797..02e09c7 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,7 @@ The first thing your plugin will have to do to gain access to this virion's API ```php final class MyPlugin extends PluginBase{ - /** @var BlockDataWorldManager */ - private $manager; + private BlockDataWorldManager $manager; protected function onEnable() : void{ $this->manager = BlockDataWorldManager::create($this); @@ -47,11 +46,9 @@ class BlockHistoryData extends BlockData{ // stores when block was placed and by return new BlockHistoryData($nbt->getString("placer"), $nbt->getLong("timestamp")); } - /** @var string */ - private $placer; + private string $placer; - /** @var int */ - private $timestamp; + private int $timestamp; public function __construct(string $placer, ?int $timestamp = null){ $this->placer = $placer; @@ -84,17 +81,17 @@ Wew, now all that's remaining is event handling! ```php public function onBlockPlace(BlockPlaceEvent $event) : void{ $block = $event->getBlock(); - $pos = $block->getPos(); + $pos = $block->getPosition(); $data = new BlockHistoryData($event->getPlayer()->getName()); - $this->manager->getWorld($pos->getWorld())->setBlockDataAt($pos->x, $pos->y, $pos->z, $data); + $this->manager->getWorld($pos->getWorld())->setBlockData($pos, $data); } public function onPlayerInteract(PlayerInteractEvent $event) : void{ if($event->getAction() === PlayerInteractEvent::RIGHT_CLICK_BLOCK && $event->getItem()->getId() === ItemIds::STICK){ $block = $event->getBlock(); - $pos = $block->getPos(); + $pos = $block->getPosition(); - $data = $this->manager->get($pos->getWorld())->getBlockDataAt($pos->x, $pos->y, $pos->z); + $data = $this->manager->get($pos->getWorld())->getBlockData($pos); if($data instanceof BlockHistoryData){ $event->getPlayer()->sendMessage(TextFormat::LIGHT_PURPLE . "This block was placed by " . TextFormat::WHITE . $data->getPlacer() . TextFormat::LIGHT_PURPLE . " on " . TextFormat::WHITE . gmdate("d-m-Y H:i:s", $data->getTimestamp())); } diff --git a/src/cosmicpe/blockdata/BlockDataFactory.php b/src/cosmicpe/blockdata/BlockDataFactory.php index 4eb1e5c..e72ce54 100644 --- a/src/cosmicpe/blockdata/BlockDataFactory.php +++ b/src/cosmicpe/blockdata/BlockDataFactory.php @@ -4,20 +4,26 @@ namespace cosmicpe\blockdata; +use InvalidArgumentException; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\Utils; final class BlockDataFactory{ private const TAG_BLOCK_TYPE = "Type"; private const TAG_BLOCK_DATA = "Data"; - /** @var BlockData[]|string[] */ - private static $types = []; + /** @phpstan-var array> */ + private static array $types = []; - /** @var string[] */ - private static $class_types = []; + /** @phpstan-var array, string> */ + private static array $class_types = []; + /** + * @phpstan-param class-string $class + */ public static function register(string $type, string $class) : void{ + Utils::testValidInstance($class, BlockData::class); self::$types[$type] = $class; self::$class_types[$class] = $type; } @@ -27,8 +33,11 @@ public static function nbtDeserialize(CompoundTag $tag) : ?BlockData{ } public static function nbtSerialize(BlockData $data) : CompoundTag{ + if(!isset(self::$class_types[$class = get_class($data)])){ + throw new InvalidArgumentException("BlockData type " . $class . " is not registered"); + } return CompoundTag::create() - ->setString(self::TAG_BLOCK_TYPE, self::$class_types[get_class($data)]) + ->setString(self::TAG_BLOCK_TYPE, self::$class_types[$class]) ->setTag(self::TAG_BLOCK_DATA, $data->nbtSerialize()); } } \ No newline at end of file diff --git a/src/cosmicpe/blockdata/world/BlockDataChunk.php b/src/cosmicpe/blockdata/world/BlockDataChunk.php index a040dc2..cc72cfa 100644 --- a/src/cosmicpe/blockdata/world/BlockDataChunk.php +++ b/src/cosmicpe/blockdata/world/BlockDataChunk.php @@ -8,7 +8,6 @@ use cosmicpe\blockdata\BlockDataFactory; use LevelDB; use LevelDBWriteBatch; -use pocketmine\nbt\BaseNbtSerializer; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\TreeRoot; use pocketmine\world\World; @@ -16,19 +15,17 @@ final class BlockDataChunk{ - /** @var LevelDB */ - private $database; + private LevelDB $database; - /** @var BigEndianNbtSerializer */ - private $serializer; + private BigEndianNbtSerializer $serializer; - /** @var BlockData[]|null[] */ - private $block_cache = []; + /** @var array */ + private array $block_cache = []; - /** @var BlockData[]|null[] */ - private $update_queue = []; + /** @var array */ + private array $update_queue = []; - public function __construct(LevelDB $database, BaseNbtSerializer $serializer){ + public function __construct(LevelDB $database, BigEndianNbtSerializer $serializer){ $this->database = $database; $this->serializer = $serializer; } diff --git a/src/cosmicpe/blockdata/world/BlockDataWorld.php b/src/cosmicpe/blockdata/world/BlockDataWorld.php index 4cd293e..ec3bcbf 100644 --- a/src/cosmicpe/blockdata/world/BlockDataWorld.php +++ b/src/cosmicpe/blockdata/world/BlockDataWorld.php @@ -6,35 +6,28 @@ use cosmicpe\blockdata\BlockData; use LevelDB; +use pocketmine\math\Vector3; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\plugin\Plugin; +use pocketmine\world\format\Chunk; use pocketmine\world\World; +use Symfony\Component\Filesystem\Path; final class BlockDataWorld{ - /** @var BigEndianNbtSerializer */ - private $serializer; + private BigEndianNbtSerializer $serializer; - /** @var World */ - private $world; + private World $world; - /** @var LevelDB */ - private $database; + private LevelDB $database; - /** @var BlockDataChunk[] */ - private $chunks = []; + /** @var array */ + private array $chunks = []; - public function __construct(Plugin $plugin, World $world){ + public function __construct(string $directory, World $world){ $this->serializer = new BigEndianNbtSerializer(); $this->world = $world; - $directory = $plugin->getDataFolder() . "blockdata/"; - if(!is_dir($directory)){ - /** @noinspection MkdirRaceConditionInspection */ - mkdir($directory); - } - - $this->database = new LevelDB($directory . $world->getFolderName(), [ + $this->database = new LevelDB(Path::join($directory, $world->getFolderName()), [ "compression" => LEVELDB_SNAPPY_COMPRESSION, "block_size" => 64 * 1024 ]); @@ -44,12 +37,20 @@ public function getWorld() : World{ return $this->world; } + public function getBlockData(Vector3 $pos) : ?BlockData{ + return $this->getBlockDataAt($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); + } + public function getBlockDataAt(int $x, int $y, int $z) : ?BlockData{ - return $this->chunks[World::chunkHash($x >> 4, $z >> 4)]->getBlockDataAt($x, $y, $z); + return $this->chunks[World::chunkHash($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)]->getBlockDataAt($x, $y, $z); + } + + public function setBlockData(Vector3 $pos, ?BlockData $data) : void{ + $this->setBlockDataAt($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $data); } public function setBlockDataAt(int $x, int $y, int $z, ?BlockData $data) : void{ - $this->chunks[World::chunkHash($x >> 4, $z >> 4)]->setBlockDataAt($x, $y, $z, $data); + $this->chunks[World::chunkHash($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)]->setBlockDataAt($x, $y, $z, $data); } public function loadChunk(int $chunkX, int $chunkZ) : void{ diff --git a/src/cosmicpe/blockdata/world/BlockDataWorldListener.php b/src/cosmicpe/blockdata/world/BlockDataWorldListener.php index 045e4d8..5bcc7ed 100644 --- a/src/cosmicpe/blockdata/world/BlockDataWorldListener.php +++ b/src/cosmicpe/blockdata/world/BlockDataWorldListener.php @@ -16,11 +16,9 @@ final class BlockDataWorldListener implements Listener{ - /** @var Plugin */ - private $plugin; + private Plugin $plugin; - /** @var BlockDataWorldManager */ - private $manager; + private BlockDataWorldManager $manager; public function __construct(Plugin $plugin, BlockDataWorldManager $manager){ $this->plugin = $plugin; diff --git a/src/cosmicpe/blockdata/world/BlockDataWorldManager.php b/src/cosmicpe/blockdata/world/BlockDataWorldManager.php index 01897b8..a221222 100644 --- a/src/cosmicpe/blockdata/world/BlockDataWorldManager.php +++ b/src/cosmicpe/blockdata/world/BlockDataWorldManager.php @@ -10,34 +10,31 @@ final class BlockDataWorldManager{ - public static function create(Plugin $plugin) : BlockDataWorldManager{ + public static function create(Plugin $plugin, ?string $directory = null) : BlockDataWorldManager{ static $created = []; if(isset($created[$name = $plugin->getName()])){ throw new BadMethodCallException("Tried to create BlockDataWorldManager twice as " . $name); } $created[$name] = true; - $instance = new self($plugin); + $instance = new self($directory ?? $plugin->getDataFolder()); $plugin->getServer()->getPluginManager()->registerEvents(new BlockDataWorldListener($plugin, $instance), $plugin); return $instance; } - /** @var Plugin */ - private $plugin; + /** @var array */ + private array $worlds = []; - /** @var BlockDataWorld[] */ - private $worlds = []; - - private function __construct(Plugin $plugin){ - $this->plugin = $plugin; - } + private function __construct( + private string $directory, + ){} public function isLoaded(World $world) : bool{ return isset($this->worlds[$world->getId()]); } - public function load(World $world) : void{ - $this->worlds[$world->getId()] = new BlockDataWorld($this->plugin, $world); + public function load(World $world) : BlockDataWorld{ + return $this->worlds[$world->getId()] ??= new BlockDataWorld($this->directory, $world); } public function unload(World $world) : void{ diff --git a/virion.yml b/virion.yml index 0b567b8..786b7ad 100644 --- a/virion.yml +++ b/virion.yml @@ -1,5 +1,5 @@ name: BlockData antigen: cosmicpe\blockdata api: 5.0.0 -version: 0.0.3 +version: 0.0.4 author: Muqsit