mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-05 09:26:06 +00:00
Rework consistency check to tolerate dynamic type IDs
we don't actually care about the specific values, only whether all the blocks and their states have been correctly registered. I'd prefer to track all of the state data permutations, but the APIs for that are private, so tracking the number of permutations will have to suffice (this should be good enough to detect bugs anyway, and also takes way less space).
This commit is contained in:
@ -21,86 +21,31 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockTest;
|
||||
use pocketmine\block\RuntimeBlockStateRegistry;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
require dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
/* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */
|
||||
|
||||
$factory = new RuntimeBlockStateRegistry();
|
||||
$remaps = [];
|
||||
$new = [];
|
||||
foreach(RuntimeBlockStateRegistry::getInstance()->getAllKnownStates() as $index => $block){
|
||||
if($index !== $block->getStateId()){
|
||||
throw new AssumptionFailedError("State index should always match state ID");
|
||||
}
|
||||
$new[$index] = $block->getName();
|
||||
}
|
||||
$newTable = BlockTest::computeConsistencyCheckTable(RuntimeBlockStateRegistry::getInstance());
|
||||
|
||||
$oldTablePath = __DIR__ . '/block_factory_consistency_check.json';
|
||||
if(file_exists($oldTablePath)){
|
||||
$oldTable = json_decode(file_get_contents($oldTablePath), true);
|
||||
if(!is_array($oldTable)){
|
||||
throw new AssumptionFailedError("Old table should be array{knownStates: array<string, string>, stateDataBits: int}");
|
||||
}
|
||||
$old = [];
|
||||
/**
|
||||
* @var string $name
|
||||
* @var int[] $stateIds
|
||||
*/
|
||||
foreach($oldTable["knownStates"] as $name => $stateIds){
|
||||
foreach($stateIds as $stateId){
|
||||
$old[$stateId] = $name;
|
||||
}
|
||||
}
|
||||
$oldStateDataSize = $oldTable["stateDataBits"];
|
||||
$oldStateDataMask = ~(~0 << $oldStateDataSize);
|
||||
$errors = BlockTest::computeConsistencyCheckDiff($oldTablePath, $newTable);
|
||||
|
||||
if($oldStateDataSize !== Block::INTERNAL_STATE_DATA_BITS){
|
||||
echo "State data bits changed from $oldStateDataSize to " . Block::INTERNAL_STATE_DATA_BITS . "\n";
|
||||
}
|
||||
|
||||
foreach($old as $k => $name){
|
||||
[$oldId, $oldStateData] = [$k >> $oldStateDataSize, $k & $oldStateDataMask];
|
||||
$reconstructedK = ($oldId << Block::INTERNAL_STATE_DATA_BITS) | $oldStateData;
|
||||
if(!isset($new[$reconstructedK])){
|
||||
echo "Removed state for $name ($oldId:$oldStateData)\n";
|
||||
}
|
||||
}
|
||||
foreach($new as $k => $name){
|
||||
[$newId, $newStateData] = [$k >> Block::INTERNAL_STATE_DATA_BITS, $k & Block::INTERNAL_STATE_DATA_MASK];
|
||||
if($newStateData > $oldStateDataMask){
|
||||
echo "Added state for $name ($newId, $newStateData)\n";
|
||||
}else{
|
||||
$reconstructedK = ($newId << $oldStateDataSize) | $newStateData;
|
||||
if(!isset($old[$reconstructedK])){
|
||||
echo "Added state for $name ($newId:$newStateData)\n";
|
||||
}elseif($old[$reconstructedK] !== $name){
|
||||
echo "Name changed ($newId:$newStateData) " . $old[$reconstructedK] . " -> " . $name . "\n";
|
||||
}
|
||||
if(count($errors) > 0){
|
||||
echo count($errors) . " changes detected:\n";
|
||||
foreach($errors as $error){
|
||||
echo $error . "\n";
|
||||
}
|
||||
}else{
|
||||
echo "No changes detected\n";
|
||||
}
|
||||
}else{
|
||||
echo "WARNING: Unable to calculate diff, no previous consistency check file found\n";
|
||||
}
|
||||
|
||||
$newTable = [];
|
||||
foreach($new as $stateId => $name){
|
||||
$newTable[$name][] = $stateId;
|
||||
}
|
||||
ksort($newTable, SORT_STRING);
|
||||
foreach(Utils::stringifyKeys($newTable) as $name => $stateIds){
|
||||
sort($stateIds, SORT_NUMERIC);
|
||||
$newTable[$name] = $stateIds;
|
||||
}
|
||||
|
||||
file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode(
|
||||
[
|
||||
"knownStates" => $newTable,
|
||||
"stateDataBits" => Block::INTERNAL_STATE_DATA_BITS
|
||||
],
|
||||
JSON_THROW_ON_ERROR
|
||||
));
|
||||
file_put_contents($oldTablePath, json_encode($newTable, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
|
||||
|
Reference in New Issue
Block a user