From 1b3e50d0a3977449252351932392e4dc8b8c21cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Feb 2022 23:58:56 +0000 Subject: [PATCH] Implement support for remappedPropertyValuesIndex schema format --- composer.lock | 8 +- .../upgrade/BlockStateUpgradeSchemaUtils.php | 90 +++++++++++++++---- .../model/BlockStateUpgradeSchemaModel.php | 10 ++- 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/composer.lock b/composer.lock index 8fa2fa59b..8df7f6614 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "607e4766c95f448b607c05a7e5170b43f9420ab0" + "reference": "1d96dd836a77996719ed09dced6e4bba99b0fc1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/607e4766c95f448b607c05a7e5170b43f9420ab0", - "reference": "607e4766c95f448b607c05a7e5170b43f9420ab0", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/1d96dd836a77996719ed09dced6e4bba99b0fc1e", + "reference": "1d96dd836a77996719ed09dced6e4bba99b0fc1e", "shasum": "" }, "type": "library", @@ -271,7 +271,7 @@ "issues": "https://github.com/pmmp/BedrockData/issues", "source": "https://github.com/pmmp/BedrockData/tree/experimental/upgrade-tables" }, - "time": "2022-02-09T19:48:12+00:00" + "time": "2022-02-09T21:52:48+00:00" }, { "name": "pocketmine/bedrock-protocol", diff --git a/src/data/bedrock/blockstate/upgrade/BlockStateUpgradeSchemaUtils.php b/src/data/bedrock/blockstate/upgrade/BlockStateUpgradeSchemaUtils.php index 8ea14acad..72e262313 100644 --- a/src/data/bedrock/blockstate/upgrade/BlockStateUpgradeSchemaUtils.php +++ b/src/data/bedrock/blockstate/upgrade/BlockStateUpgradeSchemaUtils.php @@ -35,6 +35,7 @@ use pocketmine\nbt\tag\Tag; use pocketmine\utils\Utils; use Webmozart\PathUtil\Path; use function array_map; +use function count; use function file_get_contents; use function get_class; use function implode; @@ -43,6 +44,8 @@ use function is_object; use function is_string; use function json_decode; use function ksort; +use function str_pad; +use function strval; use const JSON_THROW_ON_ERROR; use const SORT_NUMERIC; @@ -133,14 +136,22 @@ final class BlockStateUpgradeSchemaUtils{ } } + $convertedRemappedValuesIndex = []; + foreach(Utils::stringifyKeys($model->remappedPropertyValuesIndex ?? []) as $mappingKey => $mappingValues){ + foreach($mappingValues as $k => $oldNew){ + $convertedRemappedValuesIndex[$mappingKey][$k] = new BlockStateUpgradeSchemaValueRemap( + self::jsonModelToTag($oldNew->old), + self::jsonModelToTag($oldNew->new) + ); + } + } + foreach(Utils::stringifyKeys($model->remappedPropertyValues ?? []) as $blockName => $properties){ foreach(Utils::stringifyKeys($properties) as $property => $mappedValuesKey){ - foreach($mappedValuesKey as $oldNew){ - $result->remappedPropertyValues[$blockName][$property][] = new BlockStateUpgradeSchemaValueRemap( - self::jsonModelToTag($oldNew->old), - self::jsonModelToTag($oldNew->new) - ); + if(!isset($convertedRemappedValuesIndex[$mappedValuesKey])){ + throw new \UnexpectedValueException("Missing key from schema values index $mappedValuesKey"); } + $result->remappedPropertyValues[$blockName][$property] = $convertedRemappedValuesIndex[$mappedValuesKey]; } } @@ -157,6 +168,64 @@ final class BlockStateUpgradeSchemaUtils{ return $result; } + private static function buildRemappedValuesIndex(BlockStateUpgradeSchema $schema, BlockStateUpgradeSchemaModel $model) : void{ + if(count($schema->remappedPropertyValues) === 0){ + return; + } + $dedupMapping = []; + $dedupTable = []; + $dedupTableMap = []; + $counter = 0; + + foreach(Utils::stringifyKeys($schema->remappedPropertyValues) as $blockName => $remaps){ + foreach(Utils::stringifyKeys($remaps) as $propertyName => $remappedValues){ + $remappedValuesMap = []; + foreach($remappedValues as $oldNew){ + $remappedValuesMap[$oldNew->old->toString()] = $oldNew; + } + + foreach(Utils::stringifyKeys($dedupTableMap) as $dedupName => $dedupValuesMap){ + if(count($remappedValuesMap) !== count($dedupValuesMap)){ + continue; + } + + foreach(Utils::stringifyKeys($remappedValuesMap) as $oldHash => $remappedOldNew){ + if( + !isset($dedupValuesMap[$oldHash]) || + !$remappedOldNew->old->equals($dedupValuesMap[$oldHash]->old) || + !$remappedOldNew->new->equals($dedupValuesMap[$oldHash]->new) + ){ + continue 2; + } + } + + //we found a match + $dedupMapping[$blockName][$propertyName] = $dedupName; + continue 2; + } + + //no match, add the values to the table + $newDedupName = $propertyName . "_" . str_pad(strval($counter++), 2, "0", STR_PAD_LEFT); + $dedupTableMap[$newDedupName] = $remappedValuesMap; + $dedupTable[$newDedupName] = $remappedValues; + $dedupMapping[$blockName][$propertyName] = $newDedupName; + } + } + + $modelTable = []; + foreach(Utils::stringifyKeys($dedupTable) as $dedupName => $valuePairs){ + foreach($valuePairs as $k => $pair){ + $modelTable[$dedupName][$k] = new BlockStateUpgradeSchemaModelValueRemap( + BlockStateUpgradeSchemaUtils::tagToJsonModel($pair->old), + BlockStateUpgradeSchemaUtils::tagToJsonModel($pair->new), + ); + } + } + + $model->remappedPropertyValuesIndex = $modelTable; + $model->remappedPropertyValues = $dedupMapping; + } + public static function toJsonModel(BlockStateUpgradeSchema $schema) : BlockStateUpgradeSchemaModel{ $result = new BlockStateUpgradeSchemaModel(); $result->maxVersionMajor = $schema->maxVersionMajor; @@ -173,16 +242,7 @@ final class BlockStateUpgradeSchemaUtils{ } } - foreach(Utils::stringifyKeys($schema->remappedPropertyValues) as $blockName => $properties){ - foreach(Utils::stringifyKeys($properties) as $property => $propertyValues){ - foreach($propertyValues as $oldNew){ - $result->remappedPropertyValues[$blockName][$property][] = new BlockStateUpgradeSchemaModelValueRemap( - self::tagToJsonModel($oldNew->old), - self::tagToJsonModel($oldNew->new) - ); - } - } - } + self::buildRemappedValuesIndex($schema, $result); foreach(Utils::stringifyKeys($schema->remappedStates) as $oldBlockName => $remaps){ foreach($remaps as $remap){ diff --git a/src/data/bedrock/blockstate/upgrade/model/BlockStateUpgradeSchemaModel.php b/src/data/bedrock/blockstate/upgrade/model/BlockStateUpgradeSchemaModel.php index 54357bd8d..824ca7a7a 100644 --- a/src/data/bedrock/blockstate/upgrade/model/BlockStateUpgradeSchemaModel.php +++ b/src/data/bedrock/blockstate/upgrade/model/BlockStateUpgradeSchemaModel.php @@ -64,11 +64,17 @@ final class BlockStateUpgradeSchemaModel implements \JsonSerializable{ public array $renamedProperties; /** - * @var BlockStateUpgradeSchemaModelValueRemap[][][] - * @phpstan-var array>> + * @var string[][] + * @phpstan-var array> */ public array $remappedPropertyValues; + /** + * @var BlockStateUpgradeSchemaModelValueRemap[][] + * @phpstan-var array> + */ + public array $remappedPropertyValuesIndex; + /** * @var BlockStateUpgradeSchemaModelBlockRemap[][] * @phpstan-var array>