From c871a8af0301d85834f1ca528ac56fbbeb3fa601 Mon Sep 17 00:00:00 2001 From: thebigsmileXD Date: Tue, 27 Aug 2019 21:23:33 +0200 Subject: [PATCH 01/22] Upload --- .gitignore | 1 + .poggit.yml | 9 ++ src/xenialdan/libstructure/PacketListener.php | 76 +++++++++++++ .../packet/StructureBlockUpdatePacket.php | 104 ++++++++++++++++++ .../packet/StructureEditorData.php | 26 +++++ .../libstructure/packet/StructureSettings.php | 42 +++++++ .../libstructure/tile/StructureBlockTags.php | 18 +++ .../window/StructureBlockInventory.php | 46 ++++++++ virion.yml | 6 + 9 files changed, 328 insertions(+) create mode 100644 .gitignore create mode 100644 .poggit.yml create mode 100644 src/xenialdan/libstructure/PacketListener.php create mode 100644 src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php create mode 100644 src/xenialdan/libstructure/packet/StructureEditorData.php create mode 100644 src/xenialdan/libstructure/packet/StructureSettings.php create mode 100644 src/xenialdan/libstructure/tile/StructureBlockTags.php create mode 100644 src/xenialdan/libstructure/window/StructureBlockInventory.php create mode 100644 virion.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/.poggit.yml b/.poggit.yml new file mode 100644 index 0000000..dac40bd --- /dev/null +++ b/.poggit.yml @@ -0,0 +1,9 @@ +--- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/thebigsmileXD/libstructure +branches: +- master +projects: + libstructure: + path: "" + model: virion + type: library +... diff --git a/src/xenialdan/libstructure/PacketListener.php b/src/xenialdan/libstructure/PacketListener.php new file mode 100644 index 0000000..8efcbc0 --- /dev/null +++ b/src/xenialdan/libstructure/PacketListener.php @@ -0,0 +1,76 @@ +getServer()->getPluginManager()->registerEvents(new self, $plugin); + PacketPool::registerPacket(new \xenialdan\libstructure\packet\StructureBlockUpdatePacket()); + } + + public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) + { + if ($e->getPacket() instanceof StructureBlockUpdatePacket) $this->onStructureBlockUpdatePacket($e); + if ($e->getPacket() instanceof StructureTemplateDataExportRequestPacket) $this->onStructureTemplateDataExportRequestPacket($e); + if ($e->getPacket() instanceof StructureTemplateDataExportResponsePacket) $this->onStructureTemplateDataExportResponsePacket($e); + } + + private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) + { + if (!($pk = $e->getPacket()) instanceof StructureBlockUpdatePacket) throw new \InvalidArgumentException(get_class($pk) . " is not a " . StructureBlockUpdatePacket::class); + /** @var StructureBlockUpdatePacket $pk */ + var_dump($e->getPacket()); + } + + private function onStructureTemplateDataExportRequestPacket(DataPacketReceiveEvent $e) + { + if (!($pk = $e->getPacket()) instanceof StructureTemplateDataExportRequestPacket) throw new \InvalidArgumentException(get_class($e->getPacket()) . " is not a " . StructureTemplateDataExportRequestPacket::class); + /** @var StructureTemplateDataExportRequestPacket $pk */ + Server::getInstance()->getLogger()->debug("Got StructureTemplateDataExportRequestPacket " . $e->getPacket()->getRemaining()); + } + + private function onStructureTemplateDataExportResponsePacket(DataPacketReceiveEvent $e) + { + if (!($pk = $e->getPacket()) instanceof StructureTemplateDataExportResponsePacket) throw new \InvalidArgumentException(get_class($e->getPacket()) . " is not a " . StructureTemplateDataExportResponsePacket::class); + /** @var StructureTemplateDataExportResponsePacket $pk */ + Server::getInstance()->getLogger()->debug("Got StructureTemplateDataExportResponsePacket " . $e->getPacket()->getRemaining()); + } + +} \ No newline at end of file diff --git a/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php b/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php new file mode 100644 index 0000000..1ee3512 --- /dev/null +++ b/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php @@ -0,0 +1,104 @@ +getBlockPosition($this->x, $this->y, $this->z); + $this->structureEditorData = $this->getStructureEditorData(); + $this->unknownBool = $this->getBool(); + } + + protected function encodePayload() + { + $this->putBlockPosition($this->x, $this->y, $this->z); + $this->putStructureEditorData($this->structureEditorData); + $this->putBool($this->unknownBool); + } + + public function handle(NetworkSession $session): bool + { + return $session->handleStructureBlockUpdate($this); + } + + private function getStructureEditorData(): StructureEditorData + { + $result = new StructureEditorData(); + + $result->structureName = $this->getString(); + $result->string2 = $this->getString();//probably load/fileName in load mode + $result->includePlayers = $this->getBool(); + $result->showBoundingBox = $this->getBool(); + $result->mode = $this->getVarInt(); + $result->structureSettings = $this->getStructureSettings(); + //TODO 1.13 will probably add showInvisibleBlocks (bool) + + return $result; + } + + private function getStructureSettings(): StructureSettings + { + $result = new StructureSettings(); + + $result->paletteName = $this->getString(); + $result->ignoreEntities = $this->getBool(); + $result->ignoreBlocks = $this->getBool(); + $this->getBlockPosition($result->sizeX, $result->sizeY, $result->sizeZ);//structure size + $this->getBlockPosition($result->offsetX, $result->offsetY, $result->offsetZ);//structure offset + $result->lastTouchedByPlayerId = $this->getLong(); + $result->rotation = $this->getByte(); + $result->mirror = $this->getByte(); + if (version_compare(ltrim(Server::getInstance()->getVersion(), 'v'), "1.13") === 0) { + $result->integrityValue = $this->getFloat(); + //$result->integritySeed = $this->getUnsignedVarInt();//actually UnsignedInt + $result->integritySeed = intval($this->getRemaining());//hack + } + + return $result; + } + + private function putStructureEditorData(StructureEditorData $data): void + { + $this->putString($data->structureName); + $this->putString($data->string2);//probably load/fileName in load mode + $this->putBool($data->includePlayers); + $this->putBool($data->showBoundingBox); + $this->putVarInt($data->mode); + $this->putStructureSettings($data->structureSettings); + //TODO 1.13 will probably add showInvisibleBlocks (bool) + } + + private function putStructureSettings(StructureSettings $settings): void + { + $this->putString($settings->paletteName); + $this->putBool($settings->ignoreEntities); + $this->putBool($settings->ignoreBlocks); + $this->putBlockPosition($settings->sizeX, $settings->sizeY, $settings->sizeZ);//structure size + $this->putBlockPosition($settings->offsetX, $settings->offsetY, $settings->offsetZ);//structure offset + $this->putLong($settings->lastTouchedByPlayerId); + $this->putByte($settings->rotation); + $this->putByte($settings->mirror); + if (version_compare(ltrim(Server::getInstance()->getVersion(), 'v'), "1.13") === 0) { + $this->putFloat($settings->integrityValue); + $this->putInt($settings->integritySeed);//hack//actually UnsignedInt + } + } +} \ No newline at end of file diff --git a/src/xenialdan/libstructure/packet/StructureEditorData.php b/src/xenialdan/libstructure/packet/StructureEditorData.php new file mode 100644 index 0000000..189e7a5 --- /dev/null +++ b/src/xenialdan/libstructure/packet/StructureEditorData.php @@ -0,0 +1,26 @@ +asPosition()); + } + + public function getNetworkType() : int{ + return WindowTypes::STRUCTURE_EDITOR; + } + + public function getName() : string{ + return "Structure Block"; + } + + public function getDefaultSize() : int{ + return 0; + } + + /** + * This override is here for documentation and code completion purposes only. + * @return Position + */ + public function getHolder(){ + return $this->holder; + } + + /** + * @param Player|Player[] $target + */ + public function sendContents($target) : void{ + } +} diff --git a/virion.yml b/virion.yml new file mode 100644 index 0000000..a0d3c23 --- /dev/null +++ b/virion.yml @@ -0,0 +1,6 @@ +name: libstructure +version: 0.0.0 +antigen: xenialdan\libstructure +api: [3.9] +php: [7.2] +author: XenialDan From db1b71bdcc61f29138aecdf3edc5c8bfa72f589b Mon Sep 17 00:00:00 2001 From: thebigsmileXD Date: Tue, 27 Aug 2019 23:15:56 +0200 Subject: [PATCH 02/22] Remove debug __toString() methods --- .../libstructure/packet/StructureBlockUpdatePacket.php | 4 ++++ src/xenialdan/libstructure/packet/StructureEditorData.php | 5 ----- src/xenialdan/libstructure/packet/StructureSettings.php | 5 ----- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php b/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php index 1ee3512..5fad2c7 100644 --- a/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php +++ b/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php @@ -19,12 +19,15 @@ class StructureBlockUpdatePacket extends \pocketmine\network\mcpe\protocol\Struc public $structureEditorData; /** @var bool */ public $unknownBool;//could be showInvisibleBlocks + /** @var bool */ + public $unknownBool2; protected function decodePayload() { $this->getBlockPosition($this->x, $this->y, $this->z); $this->structureEditorData = $this->getStructureEditorData(); $this->unknownBool = $this->getBool(); + $this->unknownBool2 = $this->getBool(); } protected function encodePayload() @@ -32,6 +35,7 @@ protected function encodePayload() $this->putBlockPosition($this->x, $this->y, $this->z); $this->putStructureEditorData($this->structureEditorData); $this->putBool($this->unknownBool); + $this->putBool($this->unknownBool2); } public function handle(NetworkSession $session): bool diff --git a/src/xenialdan/libstructure/packet/StructureEditorData.php b/src/xenialdan/libstructure/packet/StructureEditorData.php index 189e7a5..884d4ba 100644 --- a/src/xenialdan/libstructure/packet/StructureEditorData.php +++ b/src/xenialdan/libstructure/packet/StructureEditorData.php @@ -18,9 +18,4 @@ class StructureEditorData public $mode; /** @var StructureSettings */ public $structureSettings; - - public function __toString() - { - return PHP_EOL . implode(PHP_EOL, is_array($r = print_r($this, true))?$r:[$r]); - } } \ No newline at end of file diff --git a/src/xenialdan/libstructure/packet/StructureSettings.php b/src/xenialdan/libstructure/packet/StructureSettings.php index 7a5f942..69938bb 100644 --- a/src/xenialdan/libstructure/packet/StructureSettings.php +++ b/src/xenialdan/libstructure/packet/StructureSettings.php @@ -34,9 +34,4 @@ class StructureSettings public $integrityValue; /** @var int (uvarint) */ public $integritySeed; - - public function __toString() - { - return PHP_EOL . implode(PHP_EOL, is_array($r = print_r($this, true))?$r:[$r]); - } } \ No newline at end of file From 3d2865dc1ad00d586d181e52c981fbec83f5fd41 Mon Sep 17 00:00:00 2001 From: thebigsmileXD Date: Sat, 31 Aug 2019 21:37:59 +0200 Subject: [PATCH 03/22] Update - Use InvMenu for window handling --- src/xenialdan/libstructure/PacketListener.php | 10 +- src/xenialdan/libstructure/StructureUI.php | 232 ++++++++++++++++++ src/xenialdan/libstructure/plans.md | 5 + 3 files changed, 239 insertions(+), 8 deletions(-) create mode 100644 src/xenialdan/libstructure/StructureUI.php create mode 100644 src/xenialdan/libstructure/plans.md diff --git a/src/xenialdan/libstructure/PacketListener.php b/src/xenialdan/libstructure/PacketListener.php index 8efcbc0..dc93a7b 100644 --- a/src/xenialdan/libstructure/PacketListener.php +++ b/src/xenialdan/libstructure/PacketListener.php @@ -5,11 +5,11 @@ use pocketmine\event\Listener; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataExportRequestPacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataExportResponsePacket; use pocketmine\plugin\Plugin; use pocketmine\Server; +use xenialdan\libstructure\packet\StructureBlockUpdatePacket; class PacketListener implements Listener { @@ -42,7 +42,7 @@ public static function register(Plugin $plugin): void self::$registrant = $plugin; $plugin->getServer()->getPluginManager()->registerEvents(new self, $plugin); - PacketPool::registerPacket(new \xenialdan\libstructure\packet\StructureBlockUpdatePacket()); + PacketPool::registerPacket(new StructureBlockUpdatePacket()); } public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) @@ -61,16 +61,10 @@ private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) private function onStructureTemplateDataExportRequestPacket(DataPacketReceiveEvent $e) { - if (!($pk = $e->getPacket()) instanceof StructureTemplateDataExportRequestPacket) throw new \InvalidArgumentException(get_class($e->getPacket()) . " is not a " . StructureTemplateDataExportRequestPacket::class); - /** @var StructureTemplateDataExportRequestPacket $pk */ - Server::getInstance()->getLogger()->debug("Got StructureTemplateDataExportRequestPacket " . $e->getPacket()->getRemaining()); } private function onStructureTemplateDataExportResponsePacket(DataPacketReceiveEvent $e) { - if (!($pk = $e->getPacket()) instanceof StructureTemplateDataExportResponsePacket) throw new \InvalidArgumentException(get_class($e->getPacket()) . " is not a " . StructureTemplateDataExportResponsePacket::class); - /** @var StructureTemplateDataExportResponsePacket $pk */ - Server::getInstance()->getLogger()->debug("Got StructureTemplateDataExportResponsePacket " . $e->getPacket()->getRemaining()); } } \ No newline at end of file diff --git a/src/xenialdan/libstructure/StructureUI.php b/src/xenialdan/libstructure/StructureUI.php new file mode 100644 index 0000000..4c867d9 --- /dev/null +++ b/src/xenialdan/libstructure/StructureUI.php @@ -0,0 +1,232 @@ +readonly(); + $this->fromV3 = $fromV3; + $this->toV3 = $toV3; + parent::__construct($menu, [], 0, $title); + } + + /** + * @param Vector3 $fromV3 + * @return StructureUI + */ + public function setFromV3(Vector3 $fromV3): StructureUI + { + $this->fromV3 = $fromV3; + return $this; + } + + /** + * @param Vector3 $toV3 + * @return StructureUI + */ + public function setToV3(Vector3 $toV3): StructureUI + { + $this->toV3 = $toV3; + return $this; + } + + /** + * @param string $title + * @return StructureUI + */ + public function setTitle(string $title): StructureUI + { + $this->title = $title; + return $this; + } + + /** + * @param bool $hideStructureBlock + * @return StructureUI + */ + public function setHideStructureBlock(bool $hideStructureBlock): StructureUI + { + $this->hideStructureBlock = $hideStructureBlock; + return $this; + } + + /** + * @param bool $showPlayers + * @return StructureUI + */ + public function setShowPlayers(bool $showPlayers): StructureUI + { + $this->showPlayers = $showPlayers; + return $this; + } + + /** + * @param bool $showEntities + * @return StructureUI + */ + public function setShowEntities(bool $showEntities): StructureUI + { + $this->showEntities = $showEntities; + return $this; + } + + /** + * @param bool $showBlocks + * @return StructureUI + */ + public function setShowBlocks(bool $showBlocks): StructureUI + { + $this->showBlocks = $showBlocks; + return $this; + } + + /** + * @param bool $showBoundingBox + * @return StructureUI + */ + public function setShowBoundingBox(bool $showBoundingBox): StructureUI + { + $this->showBoundingBox = $showBoundingBox; + return $this; + } + + private function calculateOffset(Vector3 $holderV3): Vector3 + { + return $holderV3->subtract(self::getMinV3($this->fromV3, $this->toV3))->multiply(-1)->floor(); + } + + private function calculateSize(): Vector3 + { + return $this->fromV3->subtract($this->toV3)->abs()->add(1, 1, 1); + } + + /** + * @param Vector3 $v1 + * @param Vector3 $v2 + * @return Vector3 + */ + public static function getMinV3(Vector3 $v1, Vector3 $v2): Vector3 + { + return (new Vector3(min($v1->x, $v2->x), min($v1->y, $v2->y), min($v1->z, $v2->z)))->floor(); + } + + /** + * @param Vector3 $v1 + * @param Vector3 $v2 + * @return Vector3 + */ + public static function getMaxV3(Vector3 $v1, Vector3 $v2): Vector3 + { + return (new Vector3(max($v1->x, $v2->x), max($v1->y, $v2->y), max($v1->z, $v2->z)))->floor(); + } + + /* InvMenu */ + + protected function sendFakeBlockData(Player $player, HolderData $data): void + { + $block = $this->getBlock()->setComponents($data->position->x, $data->position->y, $data->position->z); + $player->getLevel()->sendBlocks([$player], [$block]); + + $tag = new CompoundTag(); + if ($data->custom_name !== null) { + $tag->setString("CustomName", $data->custom_name); + } + $offset = $this->calculateOffset($block->asVector3()); + $size = $this->calculateSize(); + var_dump("offset", $offset, "size", $size, "blockV3", $block->asVector3()); + $tag->setInt("data", (int)$this->mode); + $tag->setString("dataField", ""); + $tag->setByte("ignoreEntities", $this->showEntities ? 0 : 1); + $tag->setByte("includePlayers", $this->showPlayers ? 1 : 0); + $tag->setFloat("integrity", 100.0); + $tag->setByte("isMovable", 1); + $tag->setByte("isPowered", 0); + $tag->setByte("mirror", 0); + $tag->setByte("removeBlocks", $this->showBlocks ? 0 : 1); + $tag->setByte("rotation", 0); + $tag->setLong("seed", 0); + $tag->setByte("showBoundingBox", $this->showBoundingBox ? 1 : 0); + $tag->setString("structureName", $data->custom_name ?? $this->title ?? $this->getName()); + $tag->setInt("x", (int)$block->x); + $tag->setInt("xStructureOffset", (int)$offset->x); + $tag->setInt("xStructureSize", (int)$size->x); + $tag->setInt("y", (int)$block->y); + $tag->setInt("yStructureOffset", (int)$offset->y); + $tag->setInt("yStructureSize", (int)$size->y); + $tag->setInt("z", (int)$block->z); + $tag->setInt("zStructureOffset", (int)$offset->z); + $tag->setInt("zStructureSize", (int)$size->z); + var_dump($tag->toString()); + + $this->sendTile($player, $block, $tag); + + $this->onFakeBlockDataSend($player); + } + + public function onFakeBlockDataSendSuccess(Player $player): void + { + var_dump($this); + parent::onFakeBlockDataSendSuccess($player); + } + + public function getTileId(): string + { + return StructureBlockTags::TAG_ID; + } + + public function getName(): string + { + return "Structure Block"; + } + + public function getDefaultSize(): int + { + return 0; + } + + /** + * Returns the Minecraft PE inventory type used to show the inventory window to clients. + * @return int + */ + public function getNetworkType(): int + { + return WindowTypes::STRUCTURE_EDITOR; + } + + public function getBlock(): Block + { + return Block::get(Block::STRUCTURE_BLOCK, $this->mode); + } +} \ No newline at end of file diff --git a/src/xenialdan/libstructure/plans.md b/src/xenialdan/libstructure/plans.md new file mode 100644 index 0000000..ad6288c --- /dev/null +++ b/src/xenialdan/libstructure/plans.md @@ -0,0 +1,5 @@ +- show just UI (use invalid mode for that - nearly no buttons) +- show just bounding box +- readonly/modifiable +- do not allow placing type 0 (clicking it causes client crash) +- callback function upon modification \ No newline at end of file From ca29a3f8f2fae44aae6335bc75ccb890d9625c7b Mon Sep 17 00:00:00 2001 From: XenialDan Date: Fri, 29 May 2020 10:45:27 +0200 Subject: [PATCH 04/22] Create dump.md --- src/xenialdan/dump.md | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/xenialdan/dump.md diff --git a/src/xenialdan/dump.md b/src/xenialdan/dump.md new file mode 100644 index 0000000..26ddd37 --- /dev/null +++ b/src/xenialdan/dump.md @@ -0,0 +1,75 @@ +# NBT format output of exported.mcstructure +```php +TAG_Compound({ + 'structure_world_origin': TAG_List({ + 1, + 4, + 0, + }), + 'format_version': TAG_Int(1), + 'size': TAG_List({ + 1, + 1, + 14, + }), + 'structure': TAG_Compound({ + 'block_indices': TAG_List>({ + { + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + }, + { + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + }, + }), + 'entities': TAG_List({ + }), + 'palette': TAG_Compound({ + 'default': TAG_Compound({ + 'block_palette': TAG_List({ + { + 'name': TAG_String(minecraft:air), + 'states': TAG_Compound({ + }), + 'version': TAG_Int(17760256), + }, + { + 'name': TAG_String(minecraft:stained_glass), + 'states': TAG_Compound({ + 'color': TAG_String(white), + }), + 'version': TAG_Int(17760256), + }, + }), + 'block_position_data': TAG_Compound({ + }), + }), + }), + }), +}) +``` From 4965b14427091266b094e05a729f4ae4d9025698 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Fri, 29 May 2020 09:45:39 +0000 Subject: [PATCH 05/22] I am using gitpod, most completion missing meh --- .../libstructure/format/MCStructure.php | 7 +++ .../libstructure/format/MCStructureFile.php | 62 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/xenialdan/libstructure/format/MCStructure.php create mode 100644 src/xenialdan/libstructure/format/MCStructureFile.php diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php new file mode 100644 index 0000000..83e5541 --- /dev/null +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -0,0 +1,7 @@ + Layer + $layerHashMap = new Map(); + + ### HEADER ### + try { + $path = Utils::cleanPath(realpath($path)); + $file = new SplFileObject($path); + $file->rewind(); + //TODO test + $fread = $file->fread($file->getSize()); + if ($fread === false) throw new \StringOutOfBoundsException("Could not read file $path"); + (new LittleEndianNBTSerializer())->read($fread)//todo import + $namedTag = (new NetworkLittleEndianNBTStream())->read($contentsStateNBT); + //Load + $vs = $namedTag->getList('structure_world_origin'); + $structureWorldOrigin = new Vector3($vs[0],$vs[1],$vs[2]); + //TODO continue here + } catch (\Exception $e) { + print $e; + } + return null; + } + + /** + * Sets a note at a tick in a song + * @param int $layerIndex + * @param int $ticks + * @param int $instrument + * @param int $key + * @param Map $layerHashMap + */ + private static function setNote(int $layerIndex, int $ticks, int $instrument, int $key, Map &$layerHashMap): void + { + $layer = $layerHashMap->get($layerIndex, new Layer("", 100)); + #if ($layer === null) { + # $layer = new Layer(); + if (!$layerHashMap->hasKey($layerIndex)) $layerHashMap->put($layerIndex, $layer); + #} + $layer->setNote($ticks, new Note($instrument, $key)); + } +} \ No newline at end of file From 752557673f53b107c55565fb5263e77d6aae9a0b Mon Sep 17 00:00:00 2001 From: thebigsmileXD Date: Sun, 11 Oct 2020 15:02:17 +0200 Subject: [PATCH 06/22] Only support PM4 from now on --- virion.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/virion.yml b/virion.yml index a0d3c23..d938861 100644 --- a/virion.yml +++ b/virion.yml @@ -1,6 +1,6 @@ name: libstructure -version: 0.0.0 +version: 0.1.0 antigen: xenialdan\libstructure -api: [3.9] -php: [7.2] +api: [4.0.0] +php: [7.4] author: XenialDan From 64a69bbb19c10632889c245f1521e9deb6cc9362 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Thu, 12 Nov 2020 03:09:50 +0100 Subject: [PATCH 07/22] Fix block array order (ZYX) --- src/xenialdan/libstructure/format/MCStructure.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 82741e1..6273467 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -83,9 +83,9 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block //positions $l = $this->size->getZ(); $h = $this->size->getY(); - foreach (range(0, $this->size->getX()) as $x) { + foreach (range(0, $this->size->getZ()) as $z) { foreach (range(0, $this->size->getY()) as $y) { - foreach (range(0, $this->size->getZ()) as $z) { + foreach (range(0, $this->size->getX()) as $x) { // foreach ($blockIndicesList as $layerIndex => $layer) { // $layer = reset($layer);//only default // /** @var ListTag $layer */ From c1464b0a7669a5efc7d8faf4a2eb7f429c8cb848 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Thu, 12 Nov 2020 03:45:59 +0100 Subject: [PATCH 08/22] Add layers, remove some junk --- src/xenialdan/libstructure/StructureUI.php | 7 +- .../libstructure/format/MCStructure.php | 32 +++++- .../libstructure/format/MCStructureFile.php | 2 + .../packet/StructureBlockUpdatePacket.php | 108 ------------------ .../packet/StructureEditorData.php | 21 ---- .../libstructure/packet/StructureSettings.php | 37 ------ .../window/StructureBlockInventory.php | 12 +- 7 files changed, 39 insertions(+), 180 deletions(-) delete mode 100644 src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php delete mode 100644 src/xenialdan/libstructure/packet/StructureEditorData.php delete mode 100644 src/xenialdan/libstructure/packet/StructureSettings.php diff --git a/src/xenialdan/libstructure/StructureUI.php b/src/xenialdan/libstructure/StructureUI.php index 4c867d9..54449df 100644 --- a/src/xenialdan/libstructure/StructureUI.php +++ b/src/xenialdan/libstructure/StructureUI.php @@ -4,14 +4,10 @@ namespace xenialdan\libstructure; -use muqsit\invmenu\inventories\SingleBlockInventory; -use muqsit\invmenu\InvMenu; -use muqsit\invmenu\utils\HolderData; use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\Player; +use pocketmine\player\Player; use xenialdan\libstructure\tile\StructureBlockTags; class StructureUI extends SingleBlockInventory @@ -198,7 +194,6 @@ protected function sendFakeBlockData(Player $player, HolderData $data): void public function onFakeBlockDataSendSuccess(Player $player): void { var_dump($this); - parent::onFakeBlockDataSendSuccess($player); } public function getTileId(): string diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 6273467..45d78d5 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -3,8 +3,11 @@ namespace xenialdan\libstructure\format; use Exception; +use Generator; use InvalidArgumentException; +use OutOfBoundsException; use OutOfRangeException; +use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\math\Vector3; @@ -130,8 +133,33 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block } } //debug TODO remove - foreach ($paletteBlocks->getPalette() as $fullId) var_dump(BlockFactory::getInstance()->fromFullBlock($fullId)->getName()); - foreach ($paletteLiquids->getPalette() as $fullId) var_dump(BlockFactory::getInstance()->fromFullBlock($fullId)->getName()); + foreach ($paletteBlocks->getPalette() as $fullId) Server::getInstance()->getLogger()->debug(BlockStatesParser::printStates(BlockStatesParser::getStateByBlock(BlockFactory::getInstance()->fromFullBlock($fullId)), false)); + foreach ($paletteLiquids->getPalette() as $fullId) Server::getInstance()->getLogger()->debug(BlockStatesParser::printStates(BlockStatesParser::getStateByBlock(BlockFactory::getInstance()->fromFullBlock($fullId)), false)); + #foreach ($paletteLiquids->getPalette() as $fullId) print BlockFactory::getInstance()->fromFullBlock($fullId)->getName()); + + var_dump($paletteBlocks->getBitsPerBlock()); + $i1 = $paletteLiquids->get(3, 0, 3); + var_dump($i1, BlockFactory::getInstance()->fromFullBlock($i1)); + + $this->blockLayers = [$paletteBlocks, $paletteLiquids]; + } + + /** + * @param int $layer Zero = block layer, One = liquid layer + * @return Generator|Block[] + * @throws OutOfBoundsException + */ + public function iterateBlocks(int $layer = 0): Generator + { + if ($layer > count($this->blockLayers) || $layer < 0) throw new OutOfBoundsException('Layers must be in range 0...' . count($this->blockLayers)); + for ($x = 0; $x <= $this->size->getX(); $x++) { + for ($y = 0; $y <= $this->size->getY(); $y++) { + for ($z = 0; $z <= $this->size->getZ(); $z++) { + $fullState = $this->blockLayers[$layer]->get($x, $y, $z); + yield API::setComponents(BlockFactory::getInstance()->fromFullBlock($fullState), $x, $y, $z); + } + } + } } } \ No newline at end of file diff --git a/src/xenialdan/libstructure/format/MCStructureFile.php b/src/xenialdan/libstructure/format/MCStructureFile.php index d7b21ec..51c2ed0 100644 --- a/src/xenialdan/libstructure/format/MCStructureFile.php +++ b/src/xenialdan/libstructure/format/MCStructureFile.php @@ -32,6 +32,8 @@ class MCStructureFile public const TAG_PALETTE_BLOCK_PALETTE = 'block_palette'; public const TAG_PALETTE_BLOCK_POSITION_DATA = 'block_position_data'; public const EXTENSION_MCSTRUCTURE = '.mcstructure'; + public const LAYER_BLOCKS = 0; + public const LAYER_LIQUIDS = 1; /** * Parses a *.mcstructure file diff --git a/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php b/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php deleted file mode 100644 index 5fad2c7..0000000 --- a/src/xenialdan/libstructure/packet/StructureBlockUpdatePacket.php +++ /dev/null @@ -1,108 +0,0 @@ -getBlockPosition($this->x, $this->y, $this->z); - $this->structureEditorData = $this->getStructureEditorData(); - $this->unknownBool = $this->getBool(); - $this->unknownBool2 = $this->getBool(); - } - - protected function encodePayload() - { - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putStructureEditorData($this->structureEditorData); - $this->putBool($this->unknownBool); - $this->putBool($this->unknownBool2); - } - - public function handle(NetworkSession $session): bool - { - return $session->handleStructureBlockUpdate($this); - } - - private function getStructureEditorData(): StructureEditorData - { - $result = new StructureEditorData(); - - $result->structureName = $this->getString(); - $result->string2 = $this->getString();//probably load/fileName in load mode - $result->includePlayers = $this->getBool(); - $result->showBoundingBox = $this->getBool(); - $result->mode = $this->getVarInt(); - $result->structureSettings = $this->getStructureSettings(); - //TODO 1.13 will probably add showInvisibleBlocks (bool) - - return $result; - } - - private function getStructureSettings(): StructureSettings - { - $result = new StructureSettings(); - - $result->paletteName = $this->getString(); - $result->ignoreEntities = $this->getBool(); - $result->ignoreBlocks = $this->getBool(); - $this->getBlockPosition($result->sizeX, $result->sizeY, $result->sizeZ);//structure size - $this->getBlockPosition($result->offsetX, $result->offsetY, $result->offsetZ);//structure offset - $result->lastTouchedByPlayerId = $this->getLong(); - $result->rotation = $this->getByte(); - $result->mirror = $this->getByte(); - if (version_compare(ltrim(Server::getInstance()->getVersion(), 'v'), "1.13") === 0) { - $result->integrityValue = $this->getFloat(); - //$result->integritySeed = $this->getUnsignedVarInt();//actually UnsignedInt - $result->integritySeed = intval($this->getRemaining());//hack - } - - return $result; - } - - private function putStructureEditorData(StructureEditorData $data): void - { - $this->putString($data->structureName); - $this->putString($data->string2);//probably load/fileName in load mode - $this->putBool($data->includePlayers); - $this->putBool($data->showBoundingBox); - $this->putVarInt($data->mode); - $this->putStructureSettings($data->structureSettings); - //TODO 1.13 will probably add showInvisibleBlocks (bool) - } - - private function putStructureSettings(StructureSettings $settings): void - { - $this->putString($settings->paletteName); - $this->putBool($settings->ignoreEntities); - $this->putBool($settings->ignoreBlocks); - $this->putBlockPosition($settings->sizeX, $settings->sizeY, $settings->sizeZ);//structure size - $this->putBlockPosition($settings->offsetX, $settings->offsetY, $settings->offsetZ);//structure offset - $this->putLong($settings->lastTouchedByPlayerId); - $this->putByte($settings->rotation); - $this->putByte($settings->mirror); - if (version_compare(ltrim(Server::getInstance()->getVersion(), 'v'), "1.13") === 0) { - $this->putFloat($settings->integrityValue); - $this->putInt($settings->integritySeed);//hack//actually UnsignedInt - } - } -} \ No newline at end of file diff --git a/src/xenialdan/libstructure/packet/StructureEditorData.php b/src/xenialdan/libstructure/packet/StructureEditorData.php deleted file mode 100644 index 884d4ba..0000000 --- a/src/xenialdan/libstructure/packet/StructureEditorData.php +++ /dev/null @@ -1,21 +0,0 @@ -asPosition()); + parent::__construct($pos->asPosition(),0); } public function getNetworkType() : int{ From fb6eb1092b01076eaf59874a19805f699828e968 Mon Sep 17 00:00:00 2001 From: thebigsmileXD Date: Tue, 17 Nov 2020 00:33:28 +0100 Subject: [PATCH 09/22] Combine MCStructure* into MCStructure.php Added experimental .nbt structure support, sadly bedrock edition uses java block property format -.- #blameMojang --- .../libstructure/format/MCStructure.php | 96 +++++-- .../libstructure/format/MCStructureFile.php | 98 -------- .../libstructure/format/NBTStructure.php | 235 ++++++++++++++++++ 3 files changed, 308 insertions(+), 121 deletions(-) delete mode 100644 src/xenialdan/libstructure/format/MCStructureFile.php create mode 100644 src/xenialdan/libstructure/format/NBTStructure.php diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 45d78d5..50e97fe 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -11,18 +11,39 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\math\Vector3; +use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\UnexpectedTagTypeException; use pocketmine\Server; +use pocketmine\utils\Filesystem; use pocketmine\utils\TextFormat; use pocketmine\world\format\PalettedBlockArray; +use UnexpectedValueException; +use xenialdan\libstructure\exception\StructureFileException; +use xenialdan\libstructure\exception\StructureFormatException; use xenialdan\MagicWE2\API; use xenialdan\MagicWE2\helper\BlockStatesEntry; use xenialdan\MagicWE2\helper\BlockStatesParser; class MCStructure { + //https://github.com/df-mc/structure/blob/651c5d323dbfb24991dafdb72129e2a8a478a81b/structure.go#L66-L91 + public const TAG_STRUCTURE_WORLD_ORIGIN = 'structure_world_origin'; + public const TAG_FORMAT_VERSION = 'format_version'; + public const TAG_SIZE = 'size'; + public const TAG_STRUCTURE = 'structure'; + public const TAG_BLOCK_INDICES = 'block_indices'; + public const TAG_ENTITIES = 'entities'; + public const TAG_PALETTE = 'palette'; + public const TAG_PALETTE_DEFAULT = 'default'; + public const TAG_PALETTE_BLOCK_PALETTE = 'block_palette'; + public const TAG_PALETTE_BLOCK_POSITION_DATA = 'block_position_data'; + public const EXTENSION_MCSTRUCTURE = '.mcstructure'; + public const LAYER_BLOCKS = 0; + public const LAYER_LIQUIDS = 1; /** @var Vector3 */ private $structure_world_origin; /** @var int */ @@ -35,28 +56,63 @@ class MCStructure private $entities; /** - * MCStructure constructor. - * @param int $format_version - * @param Vector3 $structure_world_origin - * @param Vector3 $size - * @param CompoundTag $structure + * Parses a *.mcstructure file + * @param string $path path to the .mcstructure file + * @see MCStructure */ - public function __construct(int $format_version, Vector3 $structure_world_origin, Vector3 $size, CompoundTag $structure) + public function parse(string $path): void { - $this->structure_world_origin = $structure_world_origin; - $this->format_version = $format_version; + $pathext = pathinfo($path, PATHINFO_EXTENSION); + if ('.' . strtolower($pathext) !== self::EXTENSION_MCSTRUCTURE) throw new InvalidArgumentException("File extension $pathext for file $path is not " . self::EXTENSION_MCSTRUCTURE); + $path = Filesystem::cleanPath(realpath($path)); + $fread = file_get_contents($path); + if ($fread === false) throw new StructureFileException("Could not read file $path"); + $namedTag = (new LittleEndianNBTSerializer())->read($fread)->mustGetCompoundTag(); + #Server::getInstance()->getLogger()->debug($namedTag->toString(2)); + //version + $version = $namedTag->getInt(self::TAG_FORMAT_VERSION); + if ($version === null) throw new StructureFormatException(self::TAG_FORMAT_VERSION . " must be present and valid integer"); + $this->format_version = $version; + //structure origin + $structureWorldOrigin = self::parseVec3($namedTag, self::TAG_STRUCTURE_WORLD_ORIGIN, true);//TODO check if optional (makes it V3{0,0,0}) + $this->structure_world_origin = $structureWorldOrigin; + //size + $size = self::parseVec3($namedTag, self::TAG_SIZE, false); $this->size = $size; - $this->parseStructure($structure); + $this->parseStructure($namedTag->getCompoundTag(self::TAG_STRUCTURE)); + } + + /** + * @param CompoundTag $nbt + * @param string $tagName + * @param bool $optional + * @return Vector3 + * @throws UnexpectedValueException + * @throws UnexpectedTagTypeException + */ + private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional): Vector3 + { + $pos = $nbt->getListTag($tagName); + if ($pos === null and $optional) { + return new Vector3(0, 0, 0); + } + if (!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Int) { + throw new UnexpectedValueException("'$tagName' should be a List"); + } + /** @var IntTag[] $values */ + $values = $pos->getValue(); + if (count($values) !== 3) { + throw new UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); + } + return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); } private function parseStructure(CompoundTag $structure): void { $blockIndicesList = $structure->getListTag('block_indices');//list> - #var_dump($blockIndicesList->toString(2)); $entitiesList = $structure->getListTag('entities'); #var_dump($entitiesList->toString(2)); $paletteCompound = $structure->getCompoundTag('palette'); - #var_dump($paletteCompound->toString(2)); #$this->parseEntities($entitiesList);//TODO $this->parseBlockLayers($paletteCompound, $blockIndicesList); } @@ -72,13 +128,13 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block /*if($paletteCompound->count() > 1){ }*/ - $paletteDefaultTag = $paletteCompound->getCompoundTag(MCStructureFile::TAG_PALETTE_DEFAULT); + $paletteDefaultTag = $paletteCompound->getCompoundTag(self::TAG_PALETTE_DEFAULT); $paletteBlocks = new PalettedBlockArray(BlockLegacyIds::AIR << 4); $paletteLiquids = new PalettedBlockArray(BlockLegacyIds::AIR << 4); /** @var BlockStatesEntry[] $paletteArray */ $paletteArray = []; /** @var CompoundTag $blockCompoundTag */ - foreach ($paletteDefaultTag->getListTag(MCStructureFile::TAG_PALETTE_BLOCK_PALETTE) as $paletteIndex => $blockCompoundTag) { + foreach ($paletteDefaultTag->getListTag(self::TAG_PALETTE_BLOCK_PALETTE) as $paletteIndex => $blockCompoundTag) { $blockState = BlockStatesParser::getInstance()::getStateByCompound($blockCompoundTag); if ($blockState instanceof BlockStatesEntry) $paletteArray[$paletteIndex] = $blockState; else print TextFormat::RED . $blockCompoundTag . " is not BlockStatesEntry"; @@ -132,14 +188,6 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block } } } - //debug TODO remove - foreach ($paletteBlocks->getPalette() as $fullId) Server::getInstance()->getLogger()->debug(BlockStatesParser::printStates(BlockStatesParser::getStateByBlock(BlockFactory::getInstance()->fromFullBlock($fullId)), false)); - foreach ($paletteLiquids->getPalette() as $fullId) Server::getInstance()->getLogger()->debug(BlockStatesParser::printStates(BlockStatesParser::getStateByBlock(BlockFactory::getInstance()->fromFullBlock($fullId)), false)); - #foreach ($paletteLiquids->getPalette() as $fullId) print BlockFactory::getInstance()->fromFullBlock($fullId)->getName()); - - var_dump($paletteBlocks->getBitsPerBlock()); - $i1 = $paletteLiquids->get(3, 0, 3); - var_dump($i1, BlockFactory::getInstance()->fromFullBlock($i1)); $this->blockLayers = [$paletteBlocks, $paletteLiquids]; } @@ -149,14 +197,16 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block * @return Generator|Block[] * @throws OutOfBoundsException */ - public function iterateBlocks(int $layer = 0): Generator + public function blocks(int $layer = 0): Generator { if ($layer > count($this->blockLayers) || $layer < 0) throw new OutOfBoundsException('Layers must be in range 0...' . count($this->blockLayers)); for ($x = 0; $x <= $this->size->getX(); $x++) { for ($y = 0; $y <= $this->size->getY(); $y++) { for ($z = 0; $z <= $this->size->getZ(); $z++) { $fullState = $this->blockLayers[$layer]->get($x, $y, $z); - yield API::setComponents(BlockFactory::getInstance()->fromFullBlock($fullState), $x, $y, $z); + $block = BlockFactory::getInstance()->fromFullBlock($fullState); + [$block->getPos()->x,$block->getPos()->y,$block->getPos()->z] = [$x,$y,$z]; + yield $block; } } } diff --git a/src/xenialdan/libstructure/format/MCStructureFile.php b/src/xenialdan/libstructure/format/MCStructureFile.php deleted file mode 100644 index 51c2ed0..0000000 --- a/src/xenialdan/libstructure/format/MCStructureFile.php +++ /dev/null @@ -1,98 +0,0 @@ -read($fread)->mustGetCompoundTag(); - #Server::getInstance()->getLogger()->debug($namedTag->toString(2)); - //version - $version = $namedTag->getInt(self::TAG_FORMAT_VERSION); - if ($version === null) throw new StructureFormatException(self::TAG_FORMAT_VERSION . " must be present and valid integer"); - //structure origin - $structureWorldOrigin = self::parseVec3($namedTag, self::TAG_STRUCTURE_WORLD_ORIGIN, true);//TODO check if optional (makes it V3{0,0,0}) - //size - $size = self::parseVec3($namedTag, self::TAG_SIZE, false); - return new MCStructure($version, $structureWorldOrigin, $size, $namedTag->getCompoundTag(self::TAG_STRUCTURE)); - } catch (NbtDataException $e) { - Server::getInstance()->getLogger()->logException($e); - } catch (UnexpectedValueException $e) { - Server::getInstance()->getLogger()->logException($e); - } catch (UnexpectedTagTypeException $e) { - Server::getInstance()->getLogger()->logException($e); - } - throw new StructureFileException("Failed to read $path"); - } - - /** - * @param CompoundTag $nbt - * @param string $tagName - * @param bool $optional - * @return Vector3 - * @throws UnexpectedValueException - * @throws UnexpectedTagTypeException - */ - private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional): Vector3 - { - $pos = $nbt->getListTag($tagName); - if ($pos === null and $optional) { - return new Vector3(0, 0, 0); - } - if (!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Int) { - throw new UnexpectedValueException("'$tagName' should be a List"); - } - /** @var IntTag[] $values */ - $values = $pos->getValue(); - if (count($values) !== 3) { - throw new UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); - } - return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); - } -} \ No newline at end of file diff --git a/src/xenialdan/libstructure/format/NBTStructure.php b/src/xenialdan/libstructure/format/NBTStructure.php new file mode 100644 index 0000000..2d19135 --- /dev/null +++ b/src/xenialdan/libstructure/format/NBTStructure.php @@ -0,0 +1,235 @@ + */ + private $palettes; + /** @var ListTag */ + private $blocks; + /** @var ListTag */ + private $entities; + + /** + * save saves a schematic to disk. + * + * @param string $file the Schematic output file name + */ + public function save(string $file): void//TODO + { +// $nbt = new TreeRoot( +// CompoundTag::create() +// ->setByteArray("Blocks", $this->blocks) +// ->setByteArray("Data", $this->data) +// ->setShort("Length", $this->length) +// ->setShort("Width", $this->width) +// ->setShort("Height", $this->height) +// ->setString("Materials", self::MATERIALS_POCKET) +// ); +// //NOTE: Save after encoding with zlib_encode for backward compatibility. +// file_put_contents($file, zlib_encode((new BigEndianNbtSerializer())->write($nbt), ZLIB_ENCODING_GZIP)); + } + + /** + * parse parses a schematic from the file passed. + * + * @param string $file + * @throws StructureFileException + */ + public function parse(string $file): void + { + $nbt = (new BigEndianNbtSerializer())->read(zlib_decode(file_get_contents($file))); + $nbt = $nbt->getTag(); + /** @var CompoundTag $nbt */ + + //https://minecraft.gamepedia.com/Data_version + $this->version = $nbt->getInt("DataVersion", 100);//todo figure out fallback + if($this->version !== 100) throw new StructureFileException("File contains DataVersion, indicating Java structure. Java structures are not supported"); + $this->author = $nbt->getString("author", ""); + + /** @var ListTag $size */ + $size = $nbt->getListTag("size"); + $this->size = new Vector3($size->get(0)->getValue(), $size->get(1)->getValue(), $size->get(2)->getValue()); + + $this->palettes = $nbt->getListTag("palettes") ?? new ListTag([$nbt->getListTag("palette")], NBT::TAG_List); + $this->blocks = $nbt->getListTag("blocks") ?? new ListTag([], NBT::TAG_List); + $this->entities = $nbt->getListTag("entities") ?? new ListTag([$nbt->getListTag("entities")], NBT::TAG_List); + } + + /** + * @param ListTag $paletteList + * @return Block[] + */ + private function paletteToBlocks(ListTag $paletteList): array + { + /** @var Block[] $blocks */ + $blocks = []; + /** @var CompoundTag $blockCompound */ + foreach ($paletteList/*->getValue()*/ as $blockCompound) { + $id = $blockCompound->getString('Name'); + $states = []; + /** @var CompoundTag $properties */ + $properties = $blockCompound->getCompoundTag('Properties'); + if ($properties instanceof CompoundTag) + //Java/legacy hack + /*if($properties->hasTag('dataID')){ + $legacyDataId = $properties->getInt('dataID'); + //Block::getStateFromLegacyData + } else{ + if($properties->hasTag('half')){ + $legacyHalf = $properties->getString('half'); + //LegacyStructureTemplate::_mapToProperty(&v99, v19, v65); + } + if($properties->hasTag('waterlogged')){ + $legacyWaterlogged = $properties->getString('waterlogged'); + //LegacyStructureTemplate::_mapPropertyToExtraBlock(&v97, v20); + } + //while properties -> v65 = (Block *)LegacyStructureTemplate::_mapToProperty(v21, v22, v65); (v5 = Block) + }*///TODO java fixes + + /** + * @var string $name + * @var StringTag $value + */ + foreach ($properties->getValue() as $name => $value) { + $valueString = (string)$value->getValue(); + $states[] = $name . '=' . $valueString; + } + try { + $fromString = BlockStatesParser::fromString($id . '[' . implode(',', $states) . ']'); + } catch (InvalidBlockStateException $e) { + Loader::getInstance()->getLogger()->logException($e); + } + $blocks[] = reset($fromString); + } + return $blocks; + } + + /** + * returns a generator of blocks found in the schematic opened. + * @param int $palette + * @return Generator|Block[] + * @throws OutOfRangeException + */ + public function blocks(int $palette = 0): Generator + { + /** @var ListTag $paletteList */ + $paletteList = $this->palettes->get($palette); + $blockPalette = $this->paletteToBlocks($paletteList); + /** @var CompoundTag $blockTag */ + foreach ($this->blocks as $blockTag) { + /** @var ListTag $pos */ + $pos = $blockTag->getListTag("pos"); + $block = $blockPalette[$blockTag->getInt('state')]; + [$block->getPos()->x, $block->getPos()->y, $block->getPos()->z] = [$pos->get(0)->getValue(), $pos->get(1)->getValue(), $pos->get(2)->getValue()]; + yield $block; + } + } +// +// /** +// * setBlocks sets a generator of blocks to a schematic, using a bounding box to calculate the size. +// * +// * @param $bb AxisAlignedBB +// * @param Generator $blocks +// */ +// public function setBlocks(AxisAlignedBB $bb, Generator $blocks): void +// { +// /** @var Block $block */ +// $offset = new Vector3((int)$bb->minX, (int)$bb->minY, (int)$bb->minZ); +// $max = new Vector3((int)$bb->maxX, (int)$bb->maxY, (int)$bb->maxZ); +// +// $this->width = $max->x - $offset->x + 1; +// $this->length = $max->z - $offset->z + 1; +// $this->height = $max->y - $offset->y + 1; +// +// foreach ($blocks as $block) { +// $pos = $block->getPos()->subtractVector($offset); +// $index = $this->blockIndex($pos->x, $pos->y, $pos->z); +// if (strlen($this->blocks) <= $index) { +// $this->blocks .= str_repeat(chr(0), $index - strlen($this->blocks) + 1); +// } +// $this->blocks[$index] = chr($block->getId()); +// $this->data[$index] = chr($block->getMeta()); +// } +// } +// +// /** +// * setBlockArray sets a block array to a schematic. The bounds of the schematic are calculated manually. +// * +// * @param Block[] $blocks +// */ +// public function setBlockArray(array $blocks): void +// { +// $min = new Vector3(0, 0, 0); +// $max = new Vector3(0, 0, 0); +// foreach ($blocks as $block) { +// if ($block->getPos()->x < $min->x) { +// $min->x = $block->getPos()->x; +// } else if ($block->getPos()->x > $max->x) { +// $max->x = $block->getPos()->x; +// } +// if ($block->getPos()->y < $min->y) { +// $min->y = $block->getPos()->y; +// } else if ($block->getPos()->y > $max->y) { +// $max->y = $block->getPos()->y; +// } +// if ($block->getPos()->z < $min->z) { +// $min->z = $block->getPos()->z; +// } else if ($block->getPos()->z > $max->z) { +// $max->z = $block->getPos()->z; +// } +// } +// $this->height = $max->y - $min->y + 1; +// $this->width = $max->x - $min->x + 1; +// $this->length = $max->z - $min->z + 1; +// +// foreach ($blocks as $block) { +// $pos = $block->getPos()->subtractVector($min); +// $index = $this->blockIndex($pos->x, $pos->y, $pos->z); +// if (strlen($this->blocks) <= $index) { +// $this->blocks .= str_repeat(chr(0), $index - strlen($this->blocks) + 1); +// } +// $this->blocks[$index] = chr($block->getId()); +// $this->data[$index] = chr($block->getMeta()); +// } +// } + + /** + * @param int $x + * @param int $y + * @param int $z + * + * @return int + */ + protected function blockIndex(int $x, int $y, int $z): int + { + return ($y * $this->size->getZ() + $z) * $this->size->getX() + $x; + } +} From aa2bdd6663e06c4d00681386963324a3cf09c4b5 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Thu, 3 Dec 2020 13:23:15 +0100 Subject: [PATCH 10/22] Upgrade version, experimental blockentity support --- .../libstructure/format/MCStructure.php | 56 +++++++++++++++---- virion.yml | 2 +- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 50e97fe..17da8b2 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -10,6 +10,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\Tile; +use pocketmine\block\tile\TileFactory; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; @@ -21,10 +23,11 @@ use pocketmine\utils\Filesystem; use pocketmine\utils\TextFormat; use pocketmine\world\format\PalettedBlockArray; +use pocketmine\world\Position; +use pocketmine\world\World; use UnexpectedValueException; use xenialdan\libstructure\exception\StructureFileException; use xenialdan\libstructure\exception\StructureFormatException; -use xenialdan\MagicWE2\API; use xenialdan\MagicWE2\helper\BlockStatesEntry; use xenialdan\MagicWE2\helper\BlockStatesParser; @@ -41,6 +44,7 @@ class MCStructure public const TAG_PALETTE_DEFAULT = 'default'; public const TAG_PALETTE_BLOCK_PALETTE = 'block_palette'; public const TAG_PALETTE_BLOCK_POSITION_DATA = 'block_position_data'; + public const TAG_PALETTE_BLOCK_ENTITY_DATA = 'block_entity_data'; public const EXTENSION_MCSTRUCTURE = '.mcstructure'; public const LAYER_BLOCKS = 0; public const LAYER_LIQUIDS = 1; @@ -51,9 +55,11 @@ class MCStructure /** @var Vector3 */ private $size; /** @var PalettedBlockArray[] */ - private $blockLayers; - /** @var array */ - private $entities; + private $blockLayers = []; + /** @var array|CompoundTag[] */ + private $entities = []; + /** @var array|CompoundTag[] */ + private $blockEntities = []; /** * Parses a *.mcstructure file @@ -131,6 +137,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block $paletteDefaultTag = $paletteCompound->getCompoundTag(self::TAG_PALETTE_DEFAULT); $paletteBlocks = new PalettedBlockArray(BlockLegacyIds::AIR << 4); $paletteLiquids = new PalettedBlockArray(BlockLegacyIds::AIR << 4); + $blockEntities = []; /** @var BlockStatesEntry[] $paletteArray */ $paletteArray = []; /** @var CompoundTag $blockCompoundTag */ @@ -139,12 +146,15 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block if ($blockState instanceof BlockStatesEntry) $paletteArray[$paletteIndex] = $blockState; else print TextFormat::RED . $blockCompoundTag . " is not BlockStatesEntry"; } + /** @var CompoundTag $blockPositionData */ + $blockPositionData = $paletteDefaultTag->getCompoundTag(self::TAG_PALETTE_BLOCK_POSITION_DATA); //positions + var_dump($this->size); $l = $this->size->getZ(); $h = $this->size->getY(); - foreach (range(0, $this->size->getZ()) as $z) { - foreach (range(0, $this->size->getY()) as $y) { - foreach (range(0, $this->size->getX()) as $x) { + foreach (range(0, $this->size->getZ() - 1) as $z) { + foreach (range(0, $this->size->getY() - 1) as $y) { + foreach (range(0, $this->size->getX() - 1) as $x) { // foreach ($blockIndicesList as $layerIndex => $layer) { // $layer = reset($layer);//only default // /** @var ListTag $layer */ @@ -154,6 +164,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block // } // } $offset = (int)(($x * $l * $h) + ($y * $l) + $z); + var_dump($offset); //block layer /** @var ListTag $tag */ @@ -185,11 +196,18 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block } } } + //nbt + if ($blockPositionData->hasTag((string)$offset)) { + /** @var CompoundTag $tag1 */ + $tag1 = $blockPositionData->getCompoundTag((string)$offset); + $blockEntities[World::blockHash($x, $y, $z)] = $tag1->getCompoundTag(self::TAG_PALETTE_BLOCK_ENTITY_DATA); + } } } } $this->blockLayers = [$paletteBlocks, $paletteLiquids]; + $this->blockEntities = $blockEntities; } /** @@ -200,16 +218,32 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block public function blocks(int $layer = 0): Generator { if ($layer > count($this->blockLayers) || $layer < 0) throw new OutOfBoundsException('Layers must be in range 0...' . count($this->blockLayers)); - for ($x = 0; $x <= $this->size->getX(); $x++) { - for ($y = 0; $y <= $this->size->getY(); $y++) { - for ($z = 0; $z <= $this->size->getZ(); $z++) { + for ($x = 0; $x < $this->size->getX(); $x++) { + for ($y = 0; $y < $this->size->getY(); $y++) { + for ($z = 0; $z < $this->size->getZ(); $z++) { $fullState = $this->blockLayers[$layer]->get($x, $y, $z); $block = BlockFactory::getInstance()->fromFullBlock($fullState); - [$block->getPos()->x,$block->getPos()->y,$block->getPos()->z] = [$x,$y,$z]; + [$block->getPos()->x, $block->getPos()->y, $block->getPos()->z] = [$x, $y, $z]; yield $block; } } } } + public function translateBlockEntity(Position $position,Vector3 $origin): ?Tile + {//TODO offset + $hash = World::blockHash($position->getFloorX(), $position->getFloorY(), $position->getFloorZ()); + $data = $this->blockEntities[$hash] ?? null; + if ($data === null) return null; + $tile = TileFactory::getInstance()->createFromData($position->getWorld(), $data); + if ($tile === null) return null; + var_dump($position); + $position = $tile->getPos()->asVector3(); + var_dump($position); + $position = $position->subtractVector($this->structure_world_origin)->addVector($origin); + var_dump($position); + [$tile->getPos()->x, $tile->getPos()->y, $tile->getPos()->z] = [$position->x, $position->y, $position->z]; + return $tile; + } + } \ No newline at end of file diff --git a/virion.yml b/virion.yml index 1dcc0b0..43355e5 100644 --- a/virion.yml +++ b/virion.yml @@ -1,5 +1,5 @@ name: libstructure -version: 0.1.0 +version: 0.1.1 antigen: xenialdan\libstructure api: [4.0.0] php: [7.3] From 057f4363514127db7d09c184d3746cfeabb430aa Mon Sep 17 00:00:00 2001 From: XenialDan Date: Thu, 3 Dec 2020 13:30:33 +0100 Subject: [PATCH 11/22] WhY dO I OnLy BuIlD MaStEr?! --- .poggit.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.poggit.yml b/.poggit.yml index dac40bd..0f178f9 100644 --- a/.poggit.yml +++ b/.poggit.yml @@ -1,6 +1,4 @@ --- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/thebigsmileXD/libstructure -branches: -- master projects: libstructure: path: "" From f4bf449f4785e7d4368b210547c69bdf608f6bf6 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Thu, 3 Dec 2020 23:32:04 +0100 Subject: [PATCH 12/22] Fixed tile loading & fixed container item loading --- .../libstructure/format/MCStructure.php | 66 ++++++++++++++++--- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 17da8b2..7e42302 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -10,6 +10,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\Container; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; use pocketmine\math\Vector3; @@ -230,20 +231,67 @@ public function blocks(int $layer = 0): Generator } } - public function translateBlockEntity(Position $position,Vector3 $origin): ?Tile - {//TODO offset + public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile + { $hash = World::blockHash($position->getFloorX(), $position->getFloorY(), $position->getFloorZ()); $data = $this->blockEntities[$hash] ?? null; if ($data === null) return null; - $tile = TileFactory::getInstance()->createFromData($position->getWorld(), $data); + /** @var TileFactory $instance */ + $instance = TileFactory::getInstance(); + $data->setInt(Tile::TAG_X, $origin->getFloorX());//why do i have to manually change that before creation.. it won't work after creation + $data->setInt(Tile::TAG_Y, $origin->getFloorY()); + $data->setInt(Tile::TAG_Z, $origin->getFloorZ()); + + //hack to fix container items loading + if (($inventoryTag = $data->getTag(Container::TAG_ITEMS)) instanceof ListTag) { + /** @var CompoundTag $itemNBT */ + foreach ($inventoryTag as $itemNBT) { + $itemNBT->setString("id", $itemNBT->getString("Name", "minecraft:air")); + $itemNBT->removeTag("Name"); + if ($itemNBT->hasTag("tag", CompoundTag::class)) { + /** @var CompoundTag $tag */ + $tag = $itemNBT->getTag("tag", CompoundTag::class); + if ($tag->hasTag("Damage")) $tag->removeTag("Damage"); + } + } + } + +// $knownTiles = self::readAnyValue(TileFactory::getInstance(), "knownTiles"); +// $tileId = $data->getString(Tile::TAG_ID, ""); +// +// switch ($knownTiles[$tileId] ?? null) { +// case Chest::class: +// { +// if (($inventoryTag = $data->getTag(Container::TAG_ITEMS)) instanceof ListTag) { +// /** @var CompoundTag $itemNBT */ +// foreach ($inventoryTag as $itemNBT) { +// $itemNBT->setString("id", $itemNBT->getString("Name", "minecraft:air")); +// $itemNBT->removeTag("Name"); +// } +// } +// } +// } + + $tile = $instance->createFromData($position->getWorld(), $data); if ($tile === null) return null; - var_dump($position); - $position = $tile->getPos()->asVector3(); - var_dump($position); - $position = $position->subtractVector($this->structure_world_origin)->addVector($origin); - var_dump($position); - [$tile->getPos()->x, $tile->getPos()->y, $tile->getPos()->z] = [$position->x, $position->y, $position->z]; return $tile; } + /** + * Reads a value of an object, regardless of access modifiers + * @param object $object + * @param string $property + * @return mixed + */ + public static function &readAnyValue(object $object, string $property) + { + $invoke = \Closure::bind(function & () use ($property) { + return $this->$property; + }, $object, $object)->__invoke(); + /** @noinspection PhpUnnecessaryLocalVariableInspection */ + $value = &$invoke; + + return $value; + } + } \ No newline at end of file From 42923f6fa9e2082222c38041d1177988711bf436 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Fri, 4 Dec 2020 01:52:23 +0100 Subject: [PATCH 13/22] Remove debug --- src/xenialdan/libstructure/format/MCStructure.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 7e42302..fe38ade 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -13,6 +13,7 @@ use pocketmine\block\tile\Container; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; +use pocketmine\block\VanillaBlocks; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; @@ -150,7 +151,6 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block /** @var CompoundTag $blockPositionData */ $blockPositionData = $paletteDefaultTag->getCompoundTag(self::TAG_PALETTE_BLOCK_POSITION_DATA); //positions - var_dump($this->size); $l = $this->size->getZ(); $h = $this->size->getY(); foreach (range(0, $this->size->getZ() - 1) as $z) { @@ -165,7 +165,6 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block // } // } $offset = (int)(($x * $l * $h) + ($y * $l) + $z); - var_dump($offset); //block layer /** @var ListTag $tag */ @@ -175,8 +174,6 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block if (($statesEntry = $paletteArray[$i] ?? null) !== null) { try { $block = $statesEntry->toBlock(); - #API::setComponents($block, $x, $y, $z);//todo test - //todo block_entity_data (tile nbt) $paletteBlocks->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { Server::getInstance()->getLogger()->logException($e); @@ -190,7 +187,6 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block if (($statesEntry = $paletteArray[$i] ?? null) !== null) { try { $block = $statesEntry->toBlock(); - #API::setComponents($block, $x, $y, $z);//todo test $paletteLiquids->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { Server::getInstance()->getLogger()->logException($e); From dae933d0f7512fa18a60112cbc7c4bea76d19440 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sat, 13 Feb 2021 00:25:36 +0100 Subject: [PATCH 14/22] Add PHP8.0 support --- virion.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virion.yml b/virion.yml index 43355e5..138ff15 100644 --- a/virion.yml +++ b/virion.yml @@ -1,6 +1,6 @@ name: libstructure -version: 0.1.1 +version: 0.1.2 antigen: xenialdan\libstructure api: [4.0.0] -php: [7.3] +php: [ 7.3, 8.0 ] author: XenialDan From cb0aac382ea17708c8ebab0c88a2c90fbb6c277b Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sat, 13 Feb 2021 23:18:54 +0100 Subject: [PATCH 15/22] Add getSize and getStructureWorldOrigin methods --- .../libstructure/format/MCStructure.php | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index fe38ade..8f6aa03 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -176,7 +176,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block $block = $statesEntry->toBlock(); $paletteBlocks->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { - Server::getInstance()->getLogger()->logException($e); + \GlobalLogger::get()->logException($e); } } } @@ -189,7 +189,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block $block = $statesEntry->toBlock(); $paletteLiquids->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { - Server::getInstance()->getLogger()->logException($e); + \GlobalLogger::get()->logException($e); } } } @@ -290,4 +290,20 @@ public static function &readAnyValue(object $object, string $property) return $value; } + /** + * @return Vector3 + */ + public function getSize(): Vector3 + { + return $this->size; + } + + /** + * @return Vector3 + */ + public function getStructureWorldOrigin(): Vector3 + { + return $this->structure_world_origin; + } + } \ No newline at end of file From 448eb7390342d47c8e556c3beb66fd9e03e96cc6 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sat, 13 Feb 2021 23:19:29 +0100 Subject: [PATCH 16/22] Version bump --- virion.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virion.yml b/virion.yml index 138ff15..9b5e070 100644 --- a/virion.yml +++ b/virion.yml @@ -1,5 +1,5 @@ name: libstructure -version: 0.1.2 +version: 0.1.3 antigen: xenialdan\libstructure api: [4.0.0] php: [ 7.3, 8.0 ] From 6822616038a8d255f4c512ed6e40c2dc6e7b135d Mon Sep 17 00:00:00 2001 From: XenialDan Date: Tue, 9 Mar 2021 07:00:03 +0100 Subject: [PATCH 17/22] Reimplement structure block inventory + tile/block --- src/xenialdan/dump.md | 2 +- src/xenialdan/libstructure/PacketListener.php | 137 +++++---- src/xenialdan/libstructure/StructureUI.php | 227 -------------- .../libstructure/block/StructureBlock.php | 58 ++++ .../libstructure/format/MCStructure.php | 22 +- .../libstructure/format/NBTStructure.php | 11 +- .../libstructure/tile/StructureBlockTile.php | 276 ++++++++++++++++++ .../window/StructureBlockInventory.php | 42 +-- 8 files changed, 450 insertions(+), 325 deletions(-) delete mode 100644 src/xenialdan/libstructure/StructureUI.php create mode 100644 src/xenialdan/libstructure/block/StructureBlock.php create mode 100644 src/xenialdan/libstructure/tile/StructureBlockTile.php diff --git a/src/xenialdan/dump.md b/src/xenialdan/dump.md index 26ddd37..37095cf 100644 --- a/src/xenialdan/dump.md +++ b/src/xenialdan/dump.md @@ -1,5 +1,5 @@ # NBT format output of exported.mcstructure -```php +``` TAG_Compound({ 'structure_world_origin': TAG_List({ 1, diff --git a/src/xenialdan/libstructure/PacketListener.php b/src/xenialdan/libstructure/PacketListener.php index dc93a7b..13736d7 100644 --- a/src/xenialdan/libstructure/PacketListener.php +++ b/src/xenialdan/libstructure/PacketListener.php @@ -2,69 +2,106 @@ namespace xenialdan\libstructure; +use InvalidArgumentException; +use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIdentifier; +use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\TileFactory; use pocketmine\event\Listener; +use pocketmine\event\player\PlayerInteractEvent; use pocketmine\event\server\DataPacketReceiveEvent; -use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\network\mcpe\protocol\StructureTemplateDataExportRequestPacket; -use pocketmine\network\mcpe\protocol\StructureTemplateDataExportResponsePacket; +use pocketmine\item\ItemIds; +use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; +use pocketmine\network\mcpe\protocol\StructureTemplateDataRequestPacket; +use pocketmine\network\mcpe\protocol\StructureTemplateDataResponsePacket; use pocketmine\plugin\Plugin; -use pocketmine\Server; -use xenialdan\libstructure\packet\StructureBlockUpdatePacket; +use pocketmine\plugin\PluginException; +use RuntimeException; +use xenialdan\libstructure\block\StructureBlock; +use xenialdan\libstructure\tile\StructureBlockTags; +use xenialdan\libstructure\tile\StructureBlockTile; +use xenialdan\libstructure\window\StructureBlockInventory; +use xenialdan\MagicWE2\API; +use xenialdan\MagicWE2\helper\SessionHelper; +use xenialdan\MagicWE2\session\data\AssetCollection; +use xenialdan\MagicWE2\session\UserSession; class PacketListener implements Listener { - /** @var Plugin|null */ - private static $registrant; + /** @var Plugin|null */ + private static $registrant; - public static function isRegistered(): bool - { - return self::$registrant instanceof Plugin; - } + public static function isRegistered(): bool + { + return self::$registrant instanceof Plugin; + } - public static function getRegistrant(): Plugin - { - return self::$registrant; - } + public static function getRegistrant(): Plugin + { + return self::$registrant; + } - public static function unregister(): void - { - self::$registrant = null; - } + public static function unregister(): void + { + self::$registrant = null; + } - /** - * @param Plugin $plugin - */ - public static function register(Plugin $plugin): void - { - if (self::isRegistered()) { - return;//silent return - } + /** + * @param Plugin $plugin + * @throws PluginException|RuntimeException + */ + public static function register(Plugin $plugin): void + { + if (self::isRegistered()) { + return;//silent return + } - self::$registrant = $plugin; - $plugin->getServer()->getPluginManager()->registerEvents(new self, $plugin); - PacketPool::registerPacket(new StructureBlockUpdatePacket()); - } + self::$registrant = $plugin; + TileFactory::getInstance()->register(StructureBlockTile::class, [StructureBlockTags::TAG_ID, "minecraft:structure_block"]); + try { + BlockFactory::getInstance()->register(new StructureBlock(new BlockIdentifier(BlockLegacyIds::STRUCTURE_BLOCK,0, null, StructureBlockTile::class), "Structure Block")); + } catch (InvalidArgumentException $e) { + } + $plugin->getServer()->getPluginManager()->registerEvents(new self, $plugin); + } - public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) - { - if ($e->getPacket() instanceof StructureBlockUpdatePacket) $this->onStructureBlockUpdatePacket($e); - if ($e->getPacket() instanceof StructureTemplateDataExportRequestPacket) $this->onStructureTemplateDataExportRequestPacket($e); - if ($e->getPacket() instanceof StructureTemplateDataExportResponsePacket) $this->onStructureTemplateDataExportResponsePacket($e); - } + public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) + { + if ($e->getPacket() instanceof StructureBlockUpdatePacket) $this->onStructureBlockUpdatePacket($e); + if ($e->getPacket() instanceof StructureTemplateDataRequestPacket) $this->onStructureTemplateDataExportRequestPacket($e); + if ($e->getPacket() instanceof StructureTemplateDataResponsePacket) $this->onStructureTemplateDataExportResponsePacket($e); + } - private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) - { - if (!($pk = $e->getPacket()) instanceof StructureBlockUpdatePacket) throw new \InvalidArgumentException(get_class($pk) . " is not a " . StructureBlockUpdatePacket::class); - /** @var StructureBlockUpdatePacket $pk */ - var_dump($e->getPacket()); - } + private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) + { + if (!($pk = $e->getPacket()) instanceof StructureBlockUpdatePacket) return; + /** @var StructureBlockUpdatePacket $pk */ + var_dump($e->getPacket());//TODO remove + $session = $e->getOrigin(); + $window = $session->getInvManager()->getWindow($session->getInvManager()->getCurrentWindowId()); + //Hack to close the inventory (client does not send inventory close packet for structure blocks) + if($window instanceof StructureBlockInventory){ + $session->getPlayer()->removeCurrentWindow(); + } + } - private function onStructureTemplateDataExportRequestPacket(DataPacketReceiveEvent $e) - { - } - - private function onStructureTemplateDataExportResponsePacket(DataPacketReceiveEvent $e) - { - } + private function onStructureTemplateDataExportRequestPacket(DataPacketReceiveEvent $e) + { + /** @var StructureTemplateDataRequestPacket $pk */ + $pk = $e->getPacket(); + $player = $e->getOrigin()->getPlayer(); + if ($pk instanceof StructureTemplateDataRequestPacket) { + var_dump($pk);//TODO remove + } + } + private function onStructureTemplateDataExportResponsePacket(DataPacketReceiveEvent $e) + { + /** @var StructureTemplateDataResponsePacket $pk */ + $pk = $e->getPacket(); + $player = $e->getOrigin()->getPlayer(); + if ($pk instanceof StructureTemplateDataResponsePacket) { + var_dump($pk);//TODO remove + } + } } \ No newline at end of file diff --git a/src/xenialdan/libstructure/StructureUI.php b/src/xenialdan/libstructure/StructureUI.php deleted file mode 100644 index 54449df..0000000 --- a/src/xenialdan/libstructure/StructureUI.php +++ /dev/null @@ -1,227 +0,0 @@ -readonly(); - $this->fromV3 = $fromV3; - $this->toV3 = $toV3; - parent::__construct($menu, [], 0, $title); - } - - /** - * @param Vector3 $fromV3 - * @return StructureUI - */ - public function setFromV3(Vector3 $fromV3): StructureUI - { - $this->fromV3 = $fromV3; - return $this; - } - - /** - * @param Vector3 $toV3 - * @return StructureUI - */ - public function setToV3(Vector3 $toV3): StructureUI - { - $this->toV3 = $toV3; - return $this; - } - - /** - * @param string $title - * @return StructureUI - */ - public function setTitle(string $title): StructureUI - { - $this->title = $title; - return $this; - } - - /** - * @param bool $hideStructureBlock - * @return StructureUI - */ - public function setHideStructureBlock(bool $hideStructureBlock): StructureUI - { - $this->hideStructureBlock = $hideStructureBlock; - return $this; - } - - /** - * @param bool $showPlayers - * @return StructureUI - */ - public function setShowPlayers(bool $showPlayers): StructureUI - { - $this->showPlayers = $showPlayers; - return $this; - } - - /** - * @param bool $showEntities - * @return StructureUI - */ - public function setShowEntities(bool $showEntities): StructureUI - { - $this->showEntities = $showEntities; - return $this; - } - - /** - * @param bool $showBlocks - * @return StructureUI - */ - public function setShowBlocks(bool $showBlocks): StructureUI - { - $this->showBlocks = $showBlocks; - return $this; - } - - /** - * @param bool $showBoundingBox - * @return StructureUI - */ - public function setShowBoundingBox(bool $showBoundingBox): StructureUI - { - $this->showBoundingBox = $showBoundingBox; - return $this; - } - - private function calculateOffset(Vector3 $holderV3): Vector3 - { - return $holderV3->subtract(self::getMinV3($this->fromV3, $this->toV3))->multiply(-1)->floor(); - } - - private function calculateSize(): Vector3 - { - return $this->fromV3->subtract($this->toV3)->abs()->add(1, 1, 1); - } - - /** - * @param Vector3 $v1 - * @param Vector3 $v2 - * @return Vector3 - */ - public static function getMinV3(Vector3 $v1, Vector3 $v2): Vector3 - { - return (new Vector3(min($v1->x, $v2->x), min($v1->y, $v2->y), min($v1->z, $v2->z)))->floor(); - } - - /** - * @param Vector3 $v1 - * @param Vector3 $v2 - * @return Vector3 - */ - public static function getMaxV3(Vector3 $v1, Vector3 $v2): Vector3 - { - return (new Vector3(max($v1->x, $v2->x), max($v1->y, $v2->y), max($v1->z, $v2->z)))->floor(); - } - - /* InvMenu */ - - protected function sendFakeBlockData(Player $player, HolderData $data): void - { - $block = $this->getBlock()->setComponents($data->position->x, $data->position->y, $data->position->z); - $player->getLevel()->sendBlocks([$player], [$block]); - - $tag = new CompoundTag(); - if ($data->custom_name !== null) { - $tag->setString("CustomName", $data->custom_name); - } - $offset = $this->calculateOffset($block->asVector3()); - $size = $this->calculateSize(); - var_dump("offset", $offset, "size", $size, "blockV3", $block->asVector3()); - $tag->setInt("data", (int)$this->mode); - $tag->setString("dataField", ""); - $tag->setByte("ignoreEntities", $this->showEntities ? 0 : 1); - $tag->setByte("includePlayers", $this->showPlayers ? 1 : 0); - $tag->setFloat("integrity", 100.0); - $tag->setByte("isMovable", 1); - $tag->setByte("isPowered", 0); - $tag->setByte("mirror", 0); - $tag->setByte("removeBlocks", $this->showBlocks ? 0 : 1); - $tag->setByte("rotation", 0); - $tag->setLong("seed", 0); - $tag->setByte("showBoundingBox", $this->showBoundingBox ? 1 : 0); - $tag->setString("structureName", $data->custom_name ?? $this->title ?? $this->getName()); - $tag->setInt("x", (int)$block->x); - $tag->setInt("xStructureOffset", (int)$offset->x); - $tag->setInt("xStructureSize", (int)$size->x); - $tag->setInt("y", (int)$block->y); - $tag->setInt("yStructureOffset", (int)$offset->y); - $tag->setInt("yStructureSize", (int)$size->y); - $tag->setInt("z", (int)$block->z); - $tag->setInt("zStructureOffset", (int)$offset->z); - $tag->setInt("zStructureSize", (int)$size->z); - var_dump($tag->toString()); - - $this->sendTile($player, $block, $tag); - - $this->onFakeBlockDataSend($player); - } - - public function onFakeBlockDataSendSuccess(Player $player): void - { - var_dump($this); - } - - public function getTileId(): string - { - return StructureBlockTags::TAG_ID; - } - - public function getName(): string - { - return "Structure Block"; - } - - public function getDefaultSize(): int - { - return 0; - } - - /** - * Returns the Minecraft PE inventory type used to show the inventory window to clients. - * @return int - */ - public function getNetworkType(): int - { - return WindowTypes::STRUCTURE_EDITOR; - } - - public function getBlock(): Block - { - return Block::get(Block::STRUCTURE_BLOCK, $this->mode); - } -} \ No newline at end of file diff --git a/src/xenialdan/libstructure/block/StructureBlock.php b/src/xenialdan/libstructure/block/StructureBlock.php new file mode 100644 index 0000000..b6024c2 --- /dev/null +++ b/src/xenialdan/libstructure/block/StructureBlock.php @@ -0,0 +1,58 @@ +mode; + } + + public function readStateFromData(int $id, int $stateMeta): void + { + $this->mode = $stateMeta; + }*/ + + public function getStateBitmask() : int{ + return 0b101; + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null): bool + { + if ($player instanceof Player) { + $structureBlock = $this->pos->getWorld()->getTile($this->pos); + if ($structureBlock instanceof TileStructureBlock/* and $player->isCreative(true)*/) { + $player->setCurrentWindow($structureBlock->getInventory()); + //TODO remove once PMMP allows injecting to InventoryManager::createContainerOpen + $id = $player->getNetworkSession()->getInvManager()->getCurrentWindowId(); + $pk = ContainerOpenPacket::blockInvVec3($id, WindowTypes::STRUCTURE_EDITOR, $this->pos->asVector3()); + $player->getNetworkSession()->sendDataPacket($pk); + } else { + var_dump("not tile", $structureBlock); + } + } + + return true; + } +} diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 8f6aa03..513d751 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -2,26 +2,26 @@ namespace xenialdan\libstructure\format; +use Closure; use Exception; use Generator; +use GlobalLogger; use InvalidArgumentException; use OutOfBoundsException; use OutOfRangeException; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Container; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; -use pocketmine\block\VanillaBlocks; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\UnexpectedTagTypeException; -use pocketmine\Server; use pocketmine\utils\Filesystem; use pocketmine\utils\TextFormat; use pocketmine\world\format\PalettedBlockArray; @@ -66,6 +66,12 @@ class MCStructure /** * Parses a *.mcstructure file * @param string $path path to the .mcstructure file + * @throws InvalidArgumentException + * @throws StructureFileException + * @throws StructureFormatException + * @throws UnexpectedTagTypeException + * @throws UnexpectedValueException + * @throws NbtDataException * @see MCStructure */ public function parse(string $path): void @@ -96,7 +102,6 @@ public function parse(string $path): void * @param bool $optional * @return Vector3 * @throws UnexpectedValueException - * @throws UnexpectedTagTypeException */ private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional): Vector3 { @@ -176,7 +181,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block $block = $statesEntry->toBlock(); $paletteBlocks->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { - \GlobalLogger::get()->logException($e); + GlobalLogger::get()->logException($e); } } } @@ -189,7 +194,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block $block = $statesEntry->toBlock(); $paletteLiquids->set($x, $y, $z, $block->getFullId()); } catch (Exception $e) { - \GlobalLogger::get()->logException($e); + GlobalLogger::get()->logException($e); } } } @@ -209,7 +214,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block /** * @param int $layer Zero = block layer, One = liquid layer - * @return Generator|Block[] + * @return Generator * @throws OutOfBoundsException */ public function blocks(int $layer = 0): Generator @@ -232,7 +237,6 @@ public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile $hash = World::blockHash($position->getFloorX(), $position->getFloorY(), $position->getFloorZ()); $data = $this->blockEntities[$hash] ?? null; if ($data === null) return null; - /** @var TileFactory $instance */ $instance = TileFactory::getInstance(); $data->setInt(Tile::TAG_X, $origin->getFloorX());//why do i have to manually change that before creation.. it won't work after creation $data->setInt(Tile::TAG_Y, $origin->getFloorY()); @@ -281,7 +285,7 @@ public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile */ public static function &readAnyValue(object $object, string $property) { - $invoke = \Closure::bind(function & () use ($property) { + $invoke = Closure::bind(function & () use ($property) { return $this->$property; }, $object, $object)->__invoke(); /** @noinspection PhpUnnecessaryLocalVariableInspection */ diff --git a/src/xenialdan/libstructure/format/NBTStructure.php b/src/xenialdan/libstructure/format/NBTStructure.php index 2d19135..a66a79c 100644 --- a/src/xenialdan/libstructure/format/NBTStructure.php +++ b/src/xenialdan/libstructure/format/NBTStructure.php @@ -5,12 +5,13 @@ namespace xenialdan\libstructure\format; use Generator; +use InvalidArgumentException; use OutOfRangeException; use pocketmine\block\Block; -use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\Vector3; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; @@ -61,7 +62,9 @@ public function save(string $file): void//TODO * parse parses a schematic from the file passed. * * @param string $file + * @throws OutOfRangeException * @throws StructureFileException + * @throws NbtDataException */ public function parse(string $file): void { @@ -86,6 +89,8 @@ public function parse(string $file): void /** * @param ListTag $paletteList * @return Block[] + * @throws InvalidArgumentException + * @throws \pocketmine\block\utils\InvalidBlockStateException */ private function paletteToBlocks(ListTag $paletteList): array { @@ -135,8 +140,10 @@ private function paletteToBlocks(ListTag $paletteList): array /** * returns a generator of blocks found in the schematic opened. * @param int $palette - * @return Generator|Block[] + * @return Generator * @throws OutOfRangeException + * @throws InvalidArgumentException + * @throws \pocketmine\block\utils\InvalidBlockStateException */ public function blocks(int $palette = 0): Generator { diff --git a/src/xenialdan/libstructure/tile/StructureBlockTile.php b/src/xenialdan/libstructure/tile/StructureBlockTile.php new file mode 100644 index 0000000..c790669 --- /dev/null +++ b/src/xenialdan/libstructure/tile/StructureBlockTile.php @@ -0,0 +1,276 @@ +fromV3 = $this->toV3 = $this->pos->asVector3(); + $this->inventory = new StructureBlockInventory($this->pos); + var_dump("constructing tile done"); + } + + public function readSaveData(CompoundTag $nbt): void + { + //todo read structure block data + $this->loadName($nbt); + var_dump(__METHOD__); + } + + protected function writeSaveData(CompoundTag $nbt): void + { + //~todo~ write structure block data + $this->addStructureBlockData($nbt); + $nbt->setInt(StructureBlockTags::TAG_DATA, $this->mode); + $this->saveName($nbt); + var_dump(__METHOD__); + } + + protected function addAdditionalSpawnData(CompoundTag $nbt): void + { + $this->addStructureBlockData($nbt); + $this->addNameSpawnData($nbt); + var_dump($nbt->toString()); + } + + /** + * @return StructureBlockInventory + */ + public function getInventory() + { + return $this->inventory; + } + + public function getDefaultName(): string + { + return "Structure Block"; + } + + /** + * @param Vector3 $fromV3 + * @return StructureBlockTile + */ + public function setFromV3(Vector3 $fromV3): self + { + $this->fromV3 = $fromV3; + return $this; + } + + /** + * @param Vector3 $toV3 + * @return StructureBlockTile + */ + public function setToV3(Vector3 $toV3): self + { + $this->toV3 = $toV3; + return $this; + } + + /** + * @param string $title + * @return StructureBlockTile + */ + public function setTitle(string $title): self + { + $this->title = $title; + return $this; + } + + /** + * @param bool $hideStructureBlock + * @return StructureBlockTile + */ + public function setHideStructureBlock(bool $hideStructureBlock): self + { + $this->hideStructureBlock = $hideStructureBlock; + return $this; + } + + /** + * @param bool $showPlayers + * @return StructureBlockTile + */ + public function setShowPlayers(bool $showPlayers): self + { + $this->showPlayers = $showPlayers; + return $this; + } + + /** + * @param bool $showEntities + * @return StructureBlockTile + */ + public function setShowEntities(bool $showEntities): self + { + $this->showEntities = $showEntities; + return $this; + } + + /** + * @param bool $showBlocks + * @return StructureBlockTile + */ + public function setShowBlocks(bool $showBlocks): self + { + $this->showBlocks = $showBlocks; + return $this; + } + + /** + * @param bool $showBoundingBox + * @return StructureBlockTile + */ + public function setShowBoundingBox(bool $showBoundingBox): self + { + $this->showBoundingBox = $showBoundingBox; + return $this; + } + + private function calculateOffset(Vector3 $holderV3): Vector3 + { + return $holderV3->subtractVector(Vector3::minComponents($this->fromV3, $this->toV3))->multiply(-1)->floor(); + } + + private function calculateSize(): Vector3 + { + return $this->fromV3->subtractVector($this->toV3)->abs()->add(1, 1, 1); + } + + protected function addStructureBlockData(CompoundTag $nbt): void + { + $pos = $this->getPos(); + $offset = $this->calculateOffset($pos->asVector3()); + $size = $this->calculateSize(); + var_dump("offset", $offset, "size", $size, "blockV3", $pos->asVector3()); + $nbt->setInt("data", (int)$this->mode); + $nbt->setString("dataField", ""); + $nbt->setByte("ignoreEntities", $this->showEntities ? 0 : 1); + $nbt->setByte("includePlayers", $this->showPlayers ? 1 : 0); + $nbt->setFloat("integrity", 100.0); + $nbt->setByte("isMovable", 1); + $nbt->setByte("isPowered", 0); + $nbt->setByte("mirror", 0); + $nbt->setByte("removeBlocks", $this->showBlocks ? 0 : 1); + $nbt->setByte("rotation", 0); + $nbt->setLong("seed", 0); + $nbt->setByte("showBoundingBox", $this->showBoundingBox ? 1 : 0); + $nbt->setString("structureName", $this->title ?? $this->getName()); + $nbt->setInt("x", (int)$pos->x); + $nbt->setInt("xStructureOffset", (int)$offset->x); + $nbt->setInt("xStructureSize", (int)$size->x); + $nbt->setInt("y", (int)$pos->y); + $nbt->setInt("yStructureOffset", (int)$offset->y+1);//TODO remove +1 hack + $nbt->setInt("yStructureSize", (int)$size->y); + $nbt->setInt("z", (int)$pos->z); + $nbt->setInt("zStructureOffset", (int)$offset->z); + $nbt->setInt("zStructureSize", (int)$size->z); + var_dump($nbt->toString()); + } + + /** + * @return bool + */ + public function isShowPlayers(): bool + { + return $this->showPlayers; + } + + /** + * @return bool + */ + public function isShowEntities(): bool + { + return $this->showEntities; + } + + /** + * @return bool + */ + public function isShowBlocks(): bool + { + return $this->showBlocks; + } + + /** + * @return bool + */ + public function isShowBoundingBox(): bool + { + return $this->showBoundingBox; + } + + /** + * @return int + */ + public function getMode(): int + { + return $this->mode; + } + + public function getStructureEditorData(Asset $asset): StructureEditorData + { + $data = new StructureEditorData(); + $data->structureName = $asset->displayname; + $data->structureDataField = ""; + $data->includePlayers = $this->isShowPlayers(); + $data->showBoundingBox = $this->isShowBoundingBox(); + $data->structureBlockType = $this->getMode(); + $data->structureSettings = $this->getStructureSettings($asset); + $data->structureRedstoneSaveMove = 0; + return $data; + } + + private function getStructureSettings(Asset $asset): StructureSettings + { + $settings = new StructureSettings(); + $settings->paletteName = "default"; + $settings->ignoreEntities = !$this->isShowEntities(); + $settings->ignoreBlocks = !$this->isShowBlocks(); + $settings->structureSizeX = $asset->getSize()->getFloorX(); + $settings->structureSizeY = $asset->getSize()->getFloorY(); + $settings->structureSizeZ = $asset->getSize()->getFloorZ(); + $settings->structureOffsetX = 0; + $settings->structureOffsetY = 0; + $settings->structureOffsetZ = 0;//TODO position + $settings->lastTouchedByPlayerID = -1; + $settings->rotation = 0; + $settings->mirror = false; + $settings->integrityValue = 1.0; + $settings->integritySeed = 0; + $settings->pivot = $asset->getOrigin(); + return $settings; + } +} \ No newline at end of file diff --git a/src/xenialdan/libstructure/window/StructureBlockInventory.php b/src/xenialdan/libstructure/window/StructureBlockInventory.php index 98cfba2..73d944a 100644 --- a/src/xenialdan/libstructure/window/StructureBlockInventory.php +++ b/src/xenialdan/libstructure/window/StructureBlockInventory.php @@ -5,42 +5,12 @@ namespace xenialdan\libstructure\window; use pocketmine\block\inventory\BlockInventory; -use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; -use pocketmine\player\Player; use pocketmine\world\Position; -class StructureBlockInventory extends BlockInventory { - - /** @var Position */ - protected $holder; - - public function __construct(Position $pos){ - parent::__construct($pos->asPosition(),0); - } - - public function getNetworkType() : int{ - return WindowTypes::STRUCTURE_EDITOR; - } - - public function getName() : string{ - return "Structure Block"; +class StructureBlockInventory extends BlockInventory +{ + public function __construct(Position $position) + { + parent::__construct($position, 0); } - - public function getDefaultSize() : int{ - return 0; - } - - /** - * This override is here for documentation and code completion purposes only. - * @return Position - */ - public function getHolder(){ - return $this->holder; - } - - /** - * @param Player|Player[] $target - */ - public function sendContents($target) : void{ - } -} +} \ No newline at end of file From c4ee655b7f6286eb9549ef17ef61056ea412aad6 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sun, 18 Apr 2021 01:15:02 +0200 Subject: [PATCH 18/22] PMMP removed hasTag --- src/xenialdan/libstructure/format/MCStructure.php | 6 +++--- src/xenialdan/libstructure/format/NBTStructure.php | 6 +++--- virion.yml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index 513d751..ca5dff5 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -199,7 +199,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block } } //nbt - if ($blockPositionData->hasTag((string)$offset)) { + if ($blockPositionData->getTag((string)$offset) !== null) { /** @var CompoundTag $tag1 */ $tag1 = $blockPositionData->getCompoundTag((string)$offset); $blockEntities[World::blockHash($x, $y, $z)] = $tag1->getCompoundTag(self::TAG_PALETTE_BLOCK_ENTITY_DATA); @@ -248,10 +248,10 @@ public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile foreach ($inventoryTag as $itemNBT) { $itemNBT->setString("id", $itemNBT->getString("Name", "minecraft:air")); $itemNBT->removeTag("Name"); - if ($itemNBT->hasTag("tag", CompoundTag::class)) { + if ($itemNBT->getTag("tag", CompoundTag::class) !== null) { /** @var CompoundTag $tag */ $tag = $itemNBT->getTag("tag", CompoundTag::class); - if ($tag->hasTag("Damage")) $tag->removeTag("Damage"); + if ($tag->getTag("Damage") !== null) $tag->removeTag("Damage"); } } } diff --git a/src/xenialdan/libstructure/format/NBTStructure.php b/src/xenialdan/libstructure/format/NBTStructure.php index a66a79c..c3502a3 100644 --- a/src/xenialdan/libstructure/format/NBTStructure.php +++ b/src/xenialdan/libstructure/format/NBTStructure.php @@ -104,15 +104,15 @@ private function paletteToBlocks(ListTag $paletteList): array $properties = $blockCompound->getCompoundTag('Properties'); if ($properties instanceof CompoundTag) //Java/legacy hack - /*if($properties->hasTag('dataID')){ + /*if($properties->getTag('dataID') !== null){ $legacyDataId = $properties->getInt('dataID'); //Block::getStateFromLegacyData } else{ - if($properties->hasTag('half')){ + if($properties->getTag('half') !== null){ $legacyHalf = $properties->getString('half'); //LegacyStructureTemplate::_mapToProperty(&v99, v19, v65); } - if($properties->hasTag('waterlogged')){ + if($properties->getTag('waterlogged') !== null){ $legacyWaterlogged = $properties->getString('waterlogged'); //LegacyStructureTemplate::_mapPropertyToExtraBlock(&v97, v20); } diff --git a/virion.yml b/virion.yml index 9b5e070..dfba9d7 100644 --- a/virion.yml +++ b/virion.yml @@ -1,5 +1,5 @@ name: libstructure -version: 0.1.3 +version: 0.1.4 antigen: xenialdan\libstructure api: [4.0.0] php: [ 7.3, 8.0 ] From 3d9e4b1e67eee8a6b388fbe74fec49ecfb50fec2 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sun, 3 Oct 2021 16:47:25 +0200 Subject: [PATCH 19/22] Update to 1.17.x --- src/xenialdan/libstructure/PacketListener.php | 22 +++++-------- .../libstructure/block/StructureBlock.php | 4 +-- .../libstructure/format/MCStructure.php | 33 ++++++++++--------- .../libstructure/format/NBTStructure.php | 17 +++++----- .../libstructure/tile/StructureBlockTile.php | 10 +++--- .../window/StructureBlockInventory.php | 10 ++++-- virion.yml | 4 +-- 7 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/xenialdan/libstructure/PacketListener.php b/src/xenialdan/libstructure/PacketListener.php index 13736d7..10a14a1 100644 --- a/src/xenialdan/libstructure/PacketListener.php +++ b/src/xenialdan/libstructure/PacketListener.php @@ -8,9 +8,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\TileFactory; use pocketmine\event\Listener; -use pocketmine\event\player\PlayerInteractEvent; use pocketmine\event\server\DataPacketReceiveEvent; -use pocketmine\item\ItemIds; use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataRequestPacket; use pocketmine\network\mcpe\protocol\StructureTemplateDataResponsePacket; @@ -21,15 +19,11 @@ use xenialdan\libstructure\tile\StructureBlockTags; use xenialdan\libstructure\tile\StructureBlockTile; use xenialdan\libstructure\window\StructureBlockInventory; -use xenialdan\MagicWE2\API; -use xenialdan\MagicWE2\helper\SessionHelper; -use xenialdan\MagicWE2\session\data\AssetCollection; -use xenialdan\MagicWE2\session\UserSession; class PacketListener implements Listener { /** @var Plugin|null */ - private static $registrant; + private static ?Plugin $registrant = null; public static function isRegistered(): bool { @@ -57,10 +51,10 @@ public static function register(Plugin $plugin): void } self::$registrant = $plugin; - TileFactory::getInstance()->register(StructureBlockTile::class, [StructureBlockTags::TAG_ID, "minecraft:structure_block"]); try { - BlockFactory::getInstance()->register(new StructureBlock(new BlockIdentifier(BlockLegacyIds::STRUCTURE_BLOCK,0, null, StructureBlockTile::class), "Structure Block")); - } catch (InvalidArgumentException $e) { + TileFactory::getInstance()->register(StructureBlockTile::class, [StructureBlockTags::TAG_ID, "minecraft:structure_block"]); + BlockFactory::getInstance()->register(new StructureBlock(new BlockIdentifier(BlockLegacyIds::STRUCTURE_BLOCK,0, null, StructureBlockTile::class), "Structure Block"), true); + } catch (InvalidArgumentException) { } $plugin->getServer()->getPluginManager()->registerEvents(new self, $plugin); } @@ -74,8 +68,8 @@ public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) { - if (!($pk = $e->getPacket()) instanceof StructureBlockUpdatePacket) return; - /** @var StructureBlockUpdatePacket $pk */ + if (!$e->getPacket() instanceof StructureBlockUpdatePacket) return; + //** @var StructureBlockUpdatePacket $pk */ var_dump($e->getPacket());//TODO remove $session = $e->getOrigin(); $window = $session->getInvManager()->getWindow($session->getInvManager()->getCurrentWindowId()); @@ -89,7 +83,7 @@ private function onStructureTemplateDataExportRequestPacket(DataPacketReceiveEve { /** @var StructureTemplateDataRequestPacket $pk */ $pk = $e->getPacket(); - $player = $e->getOrigin()->getPlayer(); + #$player = $e->getOrigin()->getPlayer(); if ($pk instanceof StructureTemplateDataRequestPacket) { var_dump($pk);//TODO remove } @@ -99,7 +93,7 @@ private function onStructureTemplateDataExportResponsePacket(DataPacketReceiveEv { /** @var StructureTemplateDataResponsePacket $pk */ $pk = $e->getPacket(); - $player = $e->getOrigin()->getPlayer(); + #$player = $e->getOrigin()->getPlayer(); if ($pk instanceof StructureTemplateDataResponsePacket) { var_dump($pk);//TODO remove } diff --git a/src/xenialdan/libstructure/block/StructureBlock.php b/src/xenialdan/libstructure/block/StructureBlock.php index b6024c2..116996d 100644 --- a/src/xenialdan/libstructure/block/StructureBlock.php +++ b/src/xenialdan/libstructure/block/StructureBlock.php @@ -41,12 +41,12 @@ public function getStateBitmask() : int{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null): bool { if ($player instanceof Player) { - $structureBlock = $this->pos->getWorld()->getTile($this->pos); + $structureBlock = $this->position->getWorld()->getTile($this->position); if ($structureBlock instanceof TileStructureBlock/* and $player->isCreative(true)*/) { $player->setCurrentWindow($structureBlock->getInventory()); //TODO remove once PMMP allows injecting to InventoryManager::createContainerOpen $id = $player->getNetworkSession()->getInvManager()->getCurrentWindowId(); - $pk = ContainerOpenPacket::blockInvVec3($id, WindowTypes::STRUCTURE_EDITOR, $this->pos->asVector3()); + $pk = ContainerOpenPacket::blockInvVec3($id, WindowTypes::STRUCTURE_EDITOR, $this->position->asVector3()); $player->getNetworkSession()->sendDataPacket($pk); } else { var_dump("not tile", $structureBlock); diff --git a/src/xenialdan/libstructure/format/MCStructure.php b/src/xenialdan/libstructure/format/MCStructure.php index ca5dff5..b25867b 100644 --- a/src/xenialdan/libstructure/format/MCStructure.php +++ b/src/xenialdan/libstructure/format/MCStructure.php @@ -51,17 +51,17 @@ class MCStructure public const LAYER_BLOCKS = 0; public const LAYER_LIQUIDS = 1; /** @var Vector3 */ - private $structure_world_origin; + private Vector3 $structure_world_origin; /** @var int */ - private $format_version; + private int $format_version; /** @var Vector3 */ - private $size; + private Vector3 $size; /** @var PalettedBlockArray[] */ - private $blockLayers = []; + private array $blockLayers = []; /** @var array|CompoundTag[] */ - private $entities = []; + private array $entities = []; /** @var array|CompoundTag[] */ - private $blockEntities = []; + private array $blockEntities = []; /** * Parses a *.mcstructure file @@ -123,7 +123,7 @@ private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optio private function parseStructure(CompoundTag $structure): void { $blockIndicesList = $structure->getListTag('block_indices');//list> - $entitiesList = $structure->getListTag('entities'); + #$entitiesList = $structure->getListTag('entities'); #var_dump($entitiesList->toString(2)); $paletteCompound = $structure->getCompoundTag('palette'); #$this->parseEntities($entitiesList);//TODO @@ -170,10 +170,12 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block // } // } $offset = (int)(($x * $l * $h) + ($y * $l) + $z); + /** @var ListTag $tag */ + if(!$tag instanceof ListTag) continue; //block layer - /** @var ListTag $tag */ - $tag = $blockIndicesList->get(0); + if($blockIndicesList->isset(0)){ + $tag = $blockIndicesList->get(0); $blockLayer = $tag->getAllValues(); if (($i = $blockLayer[$offset] ?? -1) !== -1) { if (($statesEntry = $paletteArray[$i] ?? null) !== null) { @@ -184,8 +186,9 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block GlobalLogger::get()->logException($e); } } - } + }} //liquid layer + if($blockIndicesList->isset(1)){ $tag = $blockIndicesList->get(1); $liquidLayer = $tag->getAllValues(); if (($i = $liquidLayer[$offset] ?? -1) !== -1) { @@ -197,7 +200,7 @@ private function parseBlockLayers(?CompoundTag $paletteCompound, ?ListTag $block GlobalLogger::get()->logException($e); } } - } + }} //nbt if ($blockPositionData->getTag((string)$offset) !== null) { /** @var CompoundTag $tag1 */ @@ -225,7 +228,7 @@ public function blocks(int $layer = 0): Generator for ($z = 0; $z < $this->size->getZ(); $z++) { $fullState = $this->blockLayers[$layer]->get($x, $y, $z); $block = BlockFactory::getInstance()->fromFullBlock($fullState); - [$block->getPos()->x, $block->getPos()->y, $block->getPos()->z] = [$x, $y, $z]; + [$block->getPosition()->x, $block->getPosition()->y, $block->getPosition()->z] = [$x, $y, $z]; yield $block; } } @@ -248,9 +251,9 @@ public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile foreach ($inventoryTag as $itemNBT) { $itemNBT->setString("id", $itemNBT->getString("Name", "minecraft:air")); $itemNBT->removeTag("Name"); - if ($itemNBT->getTag("tag", CompoundTag::class) !== null) { + if ($itemNBT->getCompoundTag("tag") !== null) { /** @var CompoundTag $tag */ - $tag = $itemNBT->getTag("tag", CompoundTag::class); + $tag = $itemNBT->getCompoundTag("tag"); if ($tag->getTag("Damage") !== null) $tag->removeTag("Damage"); } } @@ -283,7 +286,7 @@ public function translateBlockEntity(Position $position, Vector3 $origin): ?Tile * @param string $property * @return mixed */ - public static function &readAnyValue(object $object, string $property) + public static function &readAnyValue(object $object, string $property): mixed { $invoke = Closure::bind(function & () use ($property) { return $this->$property; diff --git a/src/xenialdan/libstructure/format/NBTStructure.php b/src/xenialdan/libstructure/format/NBTStructure.php index c3502a3..be8ce54 100644 --- a/src/xenialdan/libstructure/format/NBTStructure.php +++ b/src/xenialdan/libstructure/format/NBTStructure.php @@ -18,6 +18,7 @@ use pocketmine\nbt\tag\StringTag; use xenialdan\libstructure\exception\StructureFileException; use xenialdan\MagicWE2\exception\InvalidBlockStateException; +use xenialdan\MagicWE2\helper\BlockQuery; use xenialdan\MagicWE2\helper\BlockStatesParser; use xenialdan\MagicWE2\Loader; use function file_get_contents; @@ -26,17 +27,17 @@ class NBTStructure { /** @var int */ - private $version; + private int $version; /** @var string */ - private $author; + private string $author; /** @var Vector3 */ - private $size; + private Vector3 $size; /** @var ListTag */ - private $palettes; + private ListTag $palettes; /** @var ListTag */ - private $blocks; + private ListTag $blocks; /** @var ListTag */ - private $entities; + private ListTag $entities; /** * save saves a schematic to disk. @@ -128,7 +129,7 @@ private function paletteToBlocks(ListTag $paletteList): array $states[] = $name . '=' . $valueString; } try { - $fromString = BlockStatesParser::fromString($id . '[' . implode(',', $states) . ']'); + $fromString = BlockStatesParser::fromString(BlockQuery::fromString($id . '[' . implode(',', $states) . ']')); } catch (InvalidBlockStateException $e) { Loader::getInstance()->getLogger()->logException($e); } @@ -155,7 +156,7 @@ public function blocks(int $palette = 0): Generator /** @var ListTag $pos */ $pos = $blockTag->getListTag("pos"); $block = $blockPalette[$blockTag->getInt('state')]; - [$block->getPos()->x, $block->getPos()->y, $block->getPos()->z] = [$pos->get(0)->getValue(), $pos->get(1)->getValue(), $pos->get(2)->getValue()]; + [$block->getPosition()->x, $block->getPosition()->y, $block->getPosition()->z] = [$pos->get(0)->getValue(), $pos->get(1)->getValue(), $pos->get(2)->getValue()]; yield $block; } } diff --git a/src/xenialdan/libstructure/tile/StructureBlockTile.php b/src/xenialdan/libstructure/tile/StructureBlockTile.php index c790669..a0556b2 100644 --- a/src/xenialdan/libstructure/tile/StructureBlockTile.php +++ b/src/xenialdan/libstructure/tile/StructureBlockTile.php @@ -38,8 +38,8 @@ public function __construct(World $world, Vector3 $pos) { var_dump("constructing tile"); parent::__construct($world, $pos); - $this->fromV3 = $this->toV3 = $this->pos->asVector3(); - $this->inventory = new StructureBlockInventory($this->pos); + $this->fromV3 = $this->toV3 = $this->position->asVector3(); + $this->inventory = new StructureBlockInventory($this->position); var_dump("constructing tile done"); } @@ -69,7 +69,7 @@ protected function addAdditionalSpawnData(CompoundTag $nbt): void /** * @return StructureBlockInventory */ - public function getInventory() + public function getInventory(): StructureBlockInventory { return $this->inventory; } @@ -171,11 +171,11 @@ private function calculateSize(): Vector3 protected function addStructureBlockData(CompoundTag $nbt): void { - $pos = $this->getPos(); + $pos = $this->getPosition(); $offset = $this->calculateOffset($pos->asVector3()); $size = $this->calculateSize(); var_dump("offset", $offset, "size", $size, "blockV3", $pos->asVector3()); - $nbt->setInt("data", (int)$this->mode); + $nbt->setInt("data", $this->mode); $nbt->setString("dataField", ""); $nbt->setByte("ignoreEntities", $this->showEntities ? 0 : 1); $nbt->setByte("includePlayers", $this->showPlayers ? 1 : 0); diff --git a/src/xenialdan/libstructure/window/StructureBlockInventory.php b/src/xenialdan/libstructure/window/StructureBlockInventory.php index 73d944a..5a4ea11 100644 --- a/src/xenialdan/libstructure/window/StructureBlockInventory.php +++ b/src/xenialdan/libstructure/window/StructureBlockInventory.php @@ -5,12 +5,16 @@ namespace xenialdan\libstructure\window; use pocketmine\block\inventory\BlockInventory; +use pocketmine\block\inventory\BlockInventoryTrait; +use pocketmine\inventory\SimpleInventory; use pocketmine\world\Position; -class StructureBlockInventory extends BlockInventory +class StructureBlockInventory extends SimpleInventory implements BlockInventory { - public function __construct(Position $position) + use BlockInventoryTrait; + public function __construct(Position $holder) { - parent::__construct($position, 0); + $this->holder = $holder; + parent::__construct(0); } } \ No newline at end of file diff --git a/virion.yml b/virion.yml index dfba9d7..5ae4839 100644 --- a/virion.yml +++ b/virion.yml @@ -1,6 +1,6 @@ name: libstructure -version: 0.1.4 +version: 0.1.5 antigen: xenialdan\libstructure api: [4.0.0] -php: [ 7.3, 8.0 ] +php: [ 7.4, 8.0 ] author: XenialDan From 4d4f178f806ea1f85b5d816f83e1fa05d37fb1a4 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sun, 3 Oct 2021 19:49:12 +0200 Subject: [PATCH 20/22] Make StructureBlockTile independent of MWE2 --- .../libstructure/tile/StructureBlockTile.php | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/xenialdan/libstructure/tile/StructureBlockTile.php b/src/xenialdan/libstructure/tile/StructureBlockTile.php index a0556b2..72894c8 100644 --- a/src/xenialdan/libstructure/tile/StructureBlockTile.php +++ b/src/xenialdan/libstructure/tile/StructureBlockTile.php @@ -14,7 +14,6 @@ use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\world\World; use xenialdan\libstructure\window\StructureBlockInventory; -use xenialdan\MagicWE2\session\data\Asset; class StructureBlockTile extends Spawnable implements Nameable, InventoryHolder { @@ -79,6 +78,14 @@ public function getDefaultName(): string return "Structure Block"; } + /** + * @return Vector3 + */ + public function getFromV3(): Vector3 + { + return $this->fromV3; + } + /** * @param Vector3 $fromV3 * @return StructureBlockTile @@ -89,6 +96,14 @@ public function setFromV3(Vector3 $fromV3): self return $this; } + /** + * @return Vector3 + */ + public function getToV3(): Vector3 + { + return $this->toV3; + } + /** * @param Vector3 $toV3 * @return StructureBlockTile @@ -99,6 +114,14 @@ public function setToV3(Vector3 $toV3): self return $this; } + /** + * @return string + */ + public function getTitle(): string + { + return $this->title ?? $this->getName(); + } + /** * @param string $title * @return StructureBlockTile @@ -159,12 +182,12 @@ public function setShowBoundingBox(bool $showBoundingBox): self return $this; } - private function calculateOffset(Vector3 $holderV3): Vector3 + public function calculateOffset(Vector3 $holderV3): Vector3 { return $holderV3->subtractVector(Vector3::minComponents($this->fromV3, $this->toV3))->multiply(-1)->floor(); } - private function calculateSize(): Vector3 + public function calculateSize(): Vector3 { return $this->fromV3->subtractVector($this->toV3)->abs()->add(1, 1, 1); } @@ -187,12 +210,12 @@ protected function addStructureBlockData(CompoundTag $nbt): void $nbt->setByte("rotation", 0); $nbt->setLong("seed", 0); $nbt->setByte("showBoundingBox", $this->showBoundingBox ? 1 : 0); - $nbt->setString("structureName", $this->title ?? $this->getName()); + $nbt->setString("structureName", $this->getTitle()); $nbt->setInt("x", (int)$pos->x); $nbt->setInt("xStructureOffset", (int)$offset->x); $nbt->setInt("xStructureSize", (int)$size->x); $nbt->setInt("y", (int)$pos->y); - $nbt->setInt("yStructureOffset", (int)$offset->y+1);//TODO remove +1 hack + $nbt->setInt("yStructureOffset", (int)$offset->y/*+1*/);//TODO remove +1 hack $nbt->setInt("yStructureSize", (int)$size->y); $nbt->setInt("z", (int)$pos->z); $nbt->setInt("zStructureOffset", (int)$offset->z); @@ -240,28 +263,28 @@ public function getMode(): int return $this->mode; } - public function getStructureEditorData(Asset $asset): StructureEditorData + public function getStructureEditorData(string $structureName,Vector3 $size, Vector3 $origin): StructureEditorData { $data = new StructureEditorData(); - $data->structureName = $asset->displayname; + $data->structureName = $structureName; $data->structureDataField = ""; $data->includePlayers = $this->isShowPlayers(); $data->showBoundingBox = $this->isShowBoundingBox(); $data->structureBlockType = $this->getMode(); - $data->structureSettings = $this->getStructureSettings($asset); + $data->structureSettings = $this->getStructureSettings($size,$origin); $data->structureRedstoneSaveMove = 0; return $data; } - private function getStructureSettings(Asset $asset): StructureSettings + private function getStructureSettings(Vector3 $size, Vector3 $origin): StructureSettings { $settings = new StructureSettings(); $settings->paletteName = "default"; $settings->ignoreEntities = !$this->isShowEntities(); $settings->ignoreBlocks = !$this->isShowBlocks(); - $settings->structureSizeX = $asset->getSize()->getFloorX(); - $settings->structureSizeY = $asset->getSize()->getFloorY(); - $settings->structureSizeZ = $asset->getSize()->getFloorZ(); + $settings->structureSizeX = $size->getFloorX(); + $settings->structureSizeY = $size->getFloorY(); + $settings->structureSizeZ = $size->getFloorZ(); $settings->structureOffsetX = 0; $settings->structureOffsetY = 0; $settings->structureOffsetZ = 0;//TODO position @@ -270,7 +293,7 @@ private function getStructureSettings(Asset $asset): StructureSettings $settings->mirror = false; $settings->integrityValue = 1.0; $settings->integritySeed = 0; - $settings->pivot = $asset->getOrigin(); + $settings->pivot = $origin; return $settings; } } \ No newline at end of file From 4a01e03b4b8903c37c7ed8d7e5c70bcde67beddd Mon Sep 17 00:00:00 2001 From: XenialDan Date: Sun, 3 Oct 2021 20:21:24 +0200 Subject: [PATCH 21/22] Drop PHP 7.4 support --- virion.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virion.yml b/virion.yml index 5ae4839..4b19379 100644 --- a/virion.yml +++ b/virion.yml @@ -2,5 +2,5 @@ name: libstructure version: 0.1.5 antigen: xenialdan\libstructure api: [4.0.0] -php: [ 7.4, 8.0 ] +php: [ 8.0 ] author: XenialDan From 05ea6da0841c0e222945ba8d5cc2ff93bcb0f699 Mon Sep 17 00:00:00 2001 From: XenialDan Date: Mon, 4 Oct 2021 00:14:56 +0200 Subject: [PATCH 22/22] Remove most var_dump's --- src/xenialdan/libstructure/PacketListener.php | 6 +++--- src/xenialdan/libstructure/block/StructureBlock.php | 4 +--- src/xenialdan/libstructure/tile/StructureBlockTile.php | 8 +------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/xenialdan/libstructure/PacketListener.php b/src/xenialdan/libstructure/PacketListener.php index 10a14a1..8a9fef0 100644 --- a/src/xenialdan/libstructure/PacketListener.php +++ b/src/xenialdan/libstructure/PacketListener.php @@ -62,15 +62,15 @@ public static function register(Plugin $plugin): void public function onDataPacketReceiveEvent(DataPacketReceiveEvent $e) { if ($e->getPacket() instanceof StructureBlockUpdatePacket) $this->onStructureBlockUpdatePacket($e); - if ($e->getPacket() instanceof StructureTemplateDataRequestPacket) $this->onStructureTemplateDataExportRequestPacket($e); - if ($e->getPacket() instanceof StructureTemplateDataResponsePacket) $this->onStructureTemplateDataExportResponsePacket($e); + //if ($e->getPacket() instanceof StructureTemplateDataRequestPacket) $this->onStructureTemplateDataExportRequestPacket($e); + //if ($e->getPacket() instanceof StructureTemplateDataResponsePacket) $this->onStructureTemplateDataExportResponsePacket($e); } private function onStructureBlockUpdatePacket(DataPacketReceiveEvent $e) { if (!$e->getPacket() instanceof StructureBlockUpdatePacket) return; //** @var StructureBlockUpdatePacket $pk */ - var_dump($e->getPacket());//TODO remove + #var_dump($e->getPacket());//TODO remove $session = $e->getOrigin(); $window = $session->getInvManager()->getWindow($session->getInvManager()->getCurrentWindowId()); //Hack to close the inventory (client does not send inventory close packet for structure blocks) diff --git a/src/xenialdan/libstructure/block/StructureBlock.php b/src/xenialdan/libstructure/block/StructureBlock.php index 116996d..5732dbe 100644 --- a/src/xenialdan/libstructure/block/StructureBlock.php +++ b/src/xenialdan/libstructure/block/StructureBlock.php @@ -42,14 +42,12 @@ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player { if ($player instanceof Player) { $structureBlock = $this->position->getWorld()->getTile($this->position); - if ($structureBlock instanceof TileStructureBlock/* and $player->isCreative(true)*/) { + if ($structureBlock instanceof TileStructureBlock and $player->isCreative(true)) { $player->setCurrentWindow($structureBlock->getInventory()); //TODO remove once PMMP allows injecting to InventoryManager::createContainerOpen $id = $player->getNetworkSession()->getInvManager()->getCurrentWindowId(); $pk = ContainerOpenPacket::blockInvVec3($id, WindowTypes::STRUCTURE_EDITOR, $this->position->asVector3()); $player->getNetworkSession()->sendDataPacket($pk); - } else { - var_dump("not tile", $structureBlock); } } diff --git a/src/xenialdan/libstructure/tile/StructureBlockTile.php b/src/xenialdan/libstructure/tile/StructureBlockTile.php index 72894c8..d4284c4 100644 --- a/src/xenialdan/libstructure/tile/StructureBlockTile.php +++ b/src/xenialdan/libstructure/tile/StructureBlockTile.php @@ -35,18 +35,15 @@ class StructureBlockTile extends Spawnable implements Nameable, InventoryHolder public function __construct(World $world, Vector3 $pos) { - var_dump("constructing tile"); parent::__construct($world, $pos); $this->fromV3 = $this->toV3 = $this->position->asVector3(); $this->inventory = new StructureBlockInventory($this->position); - var_dump("constructing tile done"); } public function readSaveData(CompoundTag $nbt): void { //todo read structure block data $this->loadName($nbt); - var_dump(__METHOD__); } protected function writeSaveData(CompoundTag $nbt): void @@ -55,14 +52,12 @@ protected function writeSaveData(CompoundTag $nbt): void $this->addStructureBlockData($nbt); $nbt->setInt(StructureBlockTags::TAG_DATA, $this->mode); $this->saveName($nbt); - var_dump(__METHOD__); } protected function addAdditionalSpawnData(CompoundTag $nbt): void { $this->addStructureBlockData($nbt); $this->addNameSpawnData($nbt); - var_dump($nbt->toString()); } /** @@ -197,7 +192,7 @@ protected function addStructureBlockData(CompoundTag $nbt): void $pos = $this->getPosition(); $offset = $this->calculateOffset($pos->asVector3()); $size = $this->calculateSize(); - var_dump("offset", $offset, "size", $size, "blockV3", $pos->asVector3()); + #var_dump("offset", $offset, "size", $size, "blockV3", $pos->asVector3()); $nbt->setInt("data", $this->mode); $nbt->setString("dataField", ""); $nbt->setByte("ignoreEntities", $this->showEntities ? 0 : 1); @@ -220,7 +215,6 @@ protected function addStructureBlockData(CompoundTag $nbt): void $nbt->setInt("z", (int)$pos->z); $nbt->setInt("zStructureOffset", (int)$offset->z); $nbt->setInt("zStructureSize", (int)$size->z); - var_dump($nbt->toString()); } /**