50    private array $stateDataToStateIdLookup = [];
 
   56    private ?array $idMetaToStateIdLookupCache = 
null;
 
   67        foreach($this->states as $stateId => $stateNbt){
 
   68            $table[$stateNbt->getStateName()][$stateNbt->getRawStateProperties()] = $stateId;
 
   72        foreach(Utils::stringifyKeys($table) as $name => $stateIds){
 
   73            if(count($stateIds) === 1){
 
   74                $this->stateDataToStateIdLookup[$name] = $stateIds[array_key_first($stateIds)];
 
   76                $this->stateDataToStateIdLookup[$name] = $stateIds;
 
 
   85    private function getIdMetaToStateIdLookup() : array{
 
   86        if($this->idMetaToStateIdLookupCache === null){
 
   90            foreach($this->states as $i => $state){
 
   91                $table[$state->getStateName()][$state->getMeta()] = $i;
 
   94            $this->idMetaToStateIdLookupCache = [];
 
   95            foreach(Utils::stringifyKeys($table) as $name => $metaToStateId){
 
   97                if(count($metaToStateId) === 1){
 
   98                    $this->idMetaToStateIdLookupCache[$name] = $metaToStateId[array_key_first($metaToStateId)];
 
  100                    $this->idMetaToStateIdLookupCache[$name] = $metaToStateId;
 
  105        return $this->idMetaToStateIdLookupCache;
 
  108    public function generateDataFromStateId(
int $networkRuntimeId) : ?BlockStateData{
 
  109        return ($this->states[$networkRuntimeId] ?? null)?->generateStateData();
 
  117        $name = $data->getName();
 
  119        $lookup = $this->stateDataToStateIdLookup[$name] ?? 
null;
 
  121            $lookup === 
null => 
null,
 
  122            is_int($lookup) => $lookup,
 
  123            is_array($lookup) => $lookup[BlockStateDictionaryEntry::encodeStateProperties($data->
getStates())] ?? 
null 
 
  132        return ($this->states[$networkRuntimeId] ?? null)?->getMeta();
 
 
  140        $metas = $this->getIdMetaToStateIdLookup()[$id] ?? null;
 
  142            $metas === 
null => 
null,
 
  143            is_int($metas) => $metas,
 
  144            is_array($metas) => $metas[$meta] ?? 
null 
 
  153    public function getStates() : array{ return $this->states; }
 
  168    public static function loadFromString(
string $blockPaletteContents, 
string $metaMapContents) : self{
 
  169        $metaMap = json_decode($metaMapContents, flags: JSON_THROW_ON_ERROR);
 
  170        if(!is_array($metaMap)){
 
  171            throw new \InvalidArgumentException(
"Invalid metaMap, expected array for root type, got " . get_debug_type($metaMap));
 
  180        foreach((
new \ReflectionClass(BlockTypeNames::class))->getConstants() as $value){
 
  181            if(is_string($value)){
 
  182                $uniqueNames[$value] = $value;
 
  186        foreach(self::loadPaletteFromString($blockPaletteContents) as $i => $state){
 
  187            $meta = $metaMap[$i] ?? 
null;
 
  189                throw new \InvalidArgumentException(
"Missing associated meta value for state $i (" . $state->toNbt() . 
")");
 
  192                throw new \InvalidArgumentException(
"Invalid metaMap offset $i, expected int, got " . get_debug_type($meta));
 
  194            $uniqueName = $uniqueNames[$state->getName()] ??= $state->getName();
 
  195            $entries[$i] = 
new BlockStateDictionaryEntry($uniqueName, $state->getStates(), $meta);
 
  198        return new self($entries);