mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-08 04:38:35 +00:00
blockstate-upgrade-schema-utils: added a command to update old schemas to a newer format
this is useful when the generator was updated with new features & optimisations, to reduce the size and/or improve readability of existing schemas.
This commit is contained in:
parent
26761c2b87
commit
33dc995cc7
@ -36,6 +36,7 @@ use pocketmine\nbt\tag\IntTag;
|
|||||||
use pocketmine\nbt\tag\StringTag;
|
use pocketmine\nbt\tag\StringTag;
|
||||||
use pocketmine\nbt\tag\Tag;
|
use pocketmine\nbt\tag\Tag;
|
||||||
use pocketmine\nbt\TreeRoot;
|
use pocketmine\nbt\TreeRoot;
|
||||||
|
use pocketmine\network\mcpe\convert\BlockStateDictionary;
|
||||||
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
||||||
use pocketmine\utils\AssumptionFailedError;
|
use pocketmine\utils\AssumptionFailedError;
|
||||||
use pocketmine\utils\Filesystem;
|
use pocketmine\utils\Filesystem;
|
||||||
@ -90,18 +91,18 @@ function encodeProperty(Tag $tag) : string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param TreeRoot[] $oldNewStateList
|
||||||
|
* @phpstan-param list<TreeRoot> $oldNewStateList
|
||||||
|
*
|
||||||
* @return BlockStateMapping[][]
|
* @return BlockStateMapping[][]
|
||||||
* @phpstan-return array<string, array<string, BlockStateMapping>>
|
* @phpstan-return array<string, array<string, BlockStateMapping>>
|
||||||
*/
|
*/
|
||||||
function loadUpgradeTable(string $file, bool $reverse) : array{
|
function buildUpgradeTableFromData(array $oldNewStateList, bool $reverse) : array{
|
||||||
$contents = Filesystem::fileGetContents($file);
|
|
||||||
$data = (new NetworkNbtSerializer())->readMultiple($contents);
|
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
for($i = 0; isset($data[$i]); $i += 2){
|
for($i = 0; isset($oldNewStateList[$i]); $i += 2){
|
||||||
$oldTag = $data[$i]->mustGetCompoundTag();
|
$oldTag = $oldNewStateList[$i]->mustGetCompoundTag();
|
||||||
$newTag = $data[$i + 1]->mustGetCompoundTag();
|
$newTag = $oldNewStateList[$i + 1]->mustGetCompoundTag();
|
||||||
$old = BlockStateData::fromNbt($reverse ? $newTag : $oldTag);
|
$old = BlockStateData::fromNbt($reverse ? $newTag : $oldTag);
|
||||||
$new = BlockStateData::fromNbt($reverse ? $oldTag : $newTag);
|
$new = BlockStateData::fromNbt($reverse ? $oldTag : $newTag);
|
||||||
|
|
||||||
@ -114,6 +115,17 @@ function loadUpgradeTable(string $file, bool $reverse) : array{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BlockStateMapping[][]
|
||||||
|
* @phpstan-return array<string, array<string, BlockStateMapping>>
|
||||||
|
*/
|
||||||
|
function loadUpgradeTableFromFile(string $file, bool $reverse) : array{
|
||||||
|
$contents = Filesystem::fileGetContents($file);
|
||||||
|
$data = (new NetworkNbtSerializer())->readMultiple($contents);
|
||||||
|
|
||||||
|
return buildUpgradeTableFromData($data, $reverse);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param BlockStateData[] $states
|
* @param BlockStateData[] $states
|
||||||
* @phpstan-param array<string, BlockStateData> $states
|
* @phpstan-param array<string, BlockStateData> $states
|
||||||
@ -640,21 +652,14 @@ function testBlockStateUpgradeSchema(array $upgradeTable, BlockStateUpgradeSchem
|
|||||||
/**
|
/**
|
||||||
* @param string[] $argv
|
* @param string[] $argv
|
||||||
*/
|
*/
|
||||||
function main(array $argv) : int{
|
function cmdGenerate(array $argv) : int{
|
||||||
if(count($argv) !== 4 || ($argv[1] !== "generate" && $argv[1] !== "test")){
|
|
||||||
fwrite(STDERR, "Required arguments: <generate|test> <palette upgrade table file> <schema output file>\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mode = $argv[1];
|
|
||||||
$upgradeTableFile = $argv[2];
|
$upgradeTableFile = $argv[2];
|
||||||
$schemaFile = $argv[3];
|
$schemaFile = $argv[3];
|
||||||
|
|
||||||
$table = loadUpgradeTable($upgradeTableFile, false);
|
$table = loadUpgradeTableFromFile($upgradeTableFile, false);
|
||||||
|
|
||||||
ksort($table, SORT_STRING);
|
ksort($table, SORT_STRING);
|
||||||
|
|
||||||
if($mode === "generate"){
|
|
||||||
$diff = generateBlockStateUpgradeSchema($table);
|
$diff = generateBlockStateUpgradeSchema($table);
|
||||||
if($diff->isEmpty()){
|
if($diff->isEmpty()){
|
||||||
\GlobalLogger::get()->warning("All states appear to be the same! No schema generated.");
|
\GlobalLogger::get()->warning("All states appear to be the same! No schema generated.");
|
||||||
@ -665,16 +670,82 @@ function main(array $argv) : int{
|
|||||||
json_encode(BlockStateUpgradeSchemaUtils::toJsonModel($diff), JSON_PRETTY_PRINT) . "\n"
|
json_encode(BlockStateUpgradeSchemaUtils::toJsonModel($diff), JSON_PRETTY_PRINT) . "\n"
|
||||||
);
|
);
|
||||||
\GlobalLogger::get()->info("Schema file $schemaFile generated successfully.");
|
\GlobalLogger::get()->info("Schema file $schemaFile generated successfully.");
|
||||||
}else{
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $argv
|
||||||
|
*/
|
||||||
|
function cmdTest(array $argv) : int{
|
||||||
|
$upgradeTableFile = $argv[2];
|
||||||
|
$schemaFile = $argv[3];
|
||||||
|
|
||||||
|
$table = loadUpgradeTableFromFile($upgradeTableFile, false);
|
||||||
|
|
||||||
|
ksort($table, SORT_STRING);
|
||||||
|
|
||||||
$schema = BlockStateUpgradeSchemaUtils::loadSchemaFromString(Filesystem::fileGetContents($schemaFile), 0);
|
$schema = BlockStateUpgradeSchemaUtils::loadSchemaFromString(Filesystem::fileGetContents($schemaFile), 0);
|
||||||
if(!testBlockStateUpgradeSchema($table, $schema)){
|
if(!testBlockStateUpgradeSchema($table, $schema)){
|
||||||
\GlobalLogger::get()->error("Schema $schemaFile does not produce the results predicted by $upgradeTableFile");
|
\GlobalLogger::get()->error("Schema $schemaFile does not produce the results predicted by $upgradeTableFile");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
\GlobalLogger::get()->info("Schema $schemaFile is valid according to $upgradeTableFile");
|
\GlobalLogger::get()->info("Schema $schemaFile is valid according to $upgradeTableFile");
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $argv
|
||||||
|
*/
|
||||||
|
function cmdUpdate(array $argv) : int{
|
||||||
|
[, , $oldSchemaFile, $oldPaletteFile, $newSchemaFile] = $argv;
|
||||||
|
|
||||||
|
$palette = BlockStateDictionary::loadPaletteFromString(Filesystem::fileGetContents($oldPaletteFile));
|
||||||
|
$schema = BlockStateUpgradeSchemaUtils::loadSchemaFromString(Filesystem::fileGetContents($oldSchemaFile), 0);
|
||||||
|
//TODO: HACK!
|
||||||
|
//the upgrader won't apply the schema if it's the same version and there's only one schema with a matching version
|
||||||
|
//ID (for performance reasons), which is a problem for testing isolated schemas
|
||||||
|
//add a dummy schema to bypass this optimization
|
||||||
|
$dummySchema = new BlockStateUpgradeSchema($schema->maxVersionMajor, $schema->maxVersionMinor, $schema->maxVersionPatch, $schema->maxVersionRevision, $schema->getSchemaId() + 1);
|
||||||
|
$upgrader = new BlockStateUpgrader([$schema, $dummySchema]);
|
||||||
|
|
||||||
|
$tags = [];
|
||||||
|
foreach($palette as $stateData){
|
||||||
|
$tags[] = new TreeRoot($stateData->toNbt());
|
||||||
|
$tags[] = new TreeRoot($upgrader->upgrade($stateData)->toNbt());
|
||||||
|
}
|
||||||
|
|
||||||
|
$upgradeTable = buildUpgradeTableFromData($tags, false);
|
||||||
|
$newSchema = generateBlockStateUpgradeSchema($upgradeTable);
|
||||||
|
file_put_contents(
|
||||||
|
$newSchemaFile,
|
||||||
|
json_encode(BlockStateUpgradeSchemaUtils::toJsonModel($newSchema), JSON_PRETTY_PRINT) . "\n"
|
||||||
|
);
|
||||||
|
\GlobalLogger::get()->info("Schema file $newSchemaFile updated to new format (from $oldSchemaFile) successfully.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $argv
|
||||||
|
*/
|
||||||
|
function main(array $argv) : int{
|
||||||
|
$options = [
|
||||||
|
"generate" => [["palette upgrade table file", "schema output file"], cmdGenerate(...)],
|
||||||
|
"test" => [["palette upgrade table file", "schema output file"], cmdTest(...)],
|
||||||
|
"update" => [["schema input file", "old palette file", "updated schema output file"], cmdUpdate(...)]
|
||||||
|
];
|
||||||
|
|
||||||
|
$selected = $argv[1] ?? null;
|
||||||
|
if($selected === null || !isset($options[$selected])){
|
||||||
|
fwrite(STDERR, "Available commands:\n");
|
||||||
|
foreach($options as $command => [$args, $callback]){
|
||||||
|
fwrite(STDERR, " - $command " . implode(" ", array_map(fn(string $a) => "<$a>", $args)) . "\n");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$callback = $options[$selected][1];
|
||||||
|
return $callback($argv);
|
||||||
|
}
|
||||||
|
|
||||||
exit(main($argv));
|
exit(main($argv));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user