From becee92e7dd984788386b429cd7d14a20022bea7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Feb 2025 02:09:53 +0000 Subject: [PATCH] Reduce the size of ItemStackData when json-encoded Many items need only the name, so we can just place the name directly in this case. JsonMapper supports hydrating the object directly from the string using the pre-existing constructor for this. --- .../CraftingManagerFromDataHelper.php | 2 +- src/crafting/json/ItemStackData.php | 15 ++++++++++++++- tests/phpstan/configs/phpstan-bugs.neon | 6 ++++++ tools/generate-bedrock-data-from-packets.php | 19 +++++++++++++------ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 3df6bfb62..7c9cdd58b 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -162,7 +162,7 @@ final class CraftingManagerFromDataHelper{ } $mapper = new \JsonMapper(); - $mapper->bStrictObjectTypeChecking = true; + $mapper->bStrictObjectTypeChecking = false; //to allow hydrating ItemStackData - since this is only used for offline data it's safe $mapper->bExceptionOnUndefinedProperty = true; $mapper->bExceptionOnMissingData = true; diff --git a/src/crafting/json/ItemStackData.php b/src/crafting/json/ItemStackData.php index 032c7da7d..bf079e920 100644 --- a/src/crafting/json/ItemStackData.php +++ b/src/crafting/json/ItemStackData.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\crafting\json; -final class ItemStackData{ +use function count; + +final class ItemStackData implements \JsonSerializable{ /** @required */ public string $name; @@ -40,4 +42,15 @@ final class ItemStackData{ public function __construct(string $name){ $this->name = $name; } + + /** + * @return mixed[]|string + */ + public function jsonSerialize() : array|string{ + $result = (array) $this; + if(count($result) === 1 && isset($result["name"])){ + return $this->name; + } + return $result; + } } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index aeb3fae29..0eea2485a 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -108,6 +108,12 @@ parameters: count: 1 path: ../../../src/crafting/ShapedRecipe.php + - + message: '#^Offset ''name'' on \*NEVER\* in isset\(\) always exists and is not nullable\.$#' + identifier: isset.offset + count: 1 + path: ../../../src/crafting/json/ItemStackData.php + - message: '#^Property pocketmine\\crash\\CrashDumpData\:\:\$parameters \(list\\) does not accept array\.$#' identifier: assign.propertyType diff --git a/tools/generate-bedrock-data-from-packets.php b/tools/generate-bedrock-data-from-packets.php index c48a4f017..04c5c3305 100644 --- a/tools/generate-bedrock-data-from-packets.php +++ b/tools/generate-bedrock-data-from-packets.php @@ -207,11 +207,18 @@ class ParserPacketHandler extends PacketHandler{ return $data; } - /** - * @return mixed[] - */ - private static function objectToOrderedArray(object $object) : array{ - $result = (array) ($object instanceof \JsonSerializable ? $object->jsonSerialize() : $object); + private static function objectToOrderedArray(object $object) : mixed{ + if($object instanceof \JsonSerializable){ + $result = $object->jsonSerialize(); + if(is_object($result)){ + $result = (array) $result; + }elseif(!is_array($result)){ + return $result; + } + }else{ + $result = (array) $object; + } + ksort($result, SORT_STRING); foreach(Utils::promoteKeys($result) as $property => $value){ @@ -278,7 +285,7 @@ class ParserPacketHandler extends PacketHandler{ file_put_contents($this->bedrockDataPath . '/required_item_list.json', json_encode($table, JSON_PRETTY_PRINT) . "\n"); echo "updating item registry\n"; - $items = array_map(function(ItemTypeEntry $entry) : array{ + $items = array_map(function(ItemTypeEntry $entry) : mixed{ return self::objectToOrderedArray($entry); }, $packet->getEntries()); file_put_contents($this->bedrockDataPath . '/item_registry.json', json_encode($items, JSON_PRETTY_PRINT) . "\n");