diff --git a/src/pocketmine/level/format/io/ChunkUtils.php b/src/pocketmine/level/format/io/ChunkUtils.php index 616432289..c44130f29 100644 --- a/src/pocketmine/level/format/io/ChunkUtils.php +++ b/src/pocketmine/level/format/io/ChunkUtils.php @@ -35,11 +35,14 @@ class ChunkUtils{ public static final function reorderByteArray(string $array) : string{ $result = str_repeat("\x00", 4096); $i = 0; + $zM = 0; + $yM = 0; for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 256; $z += 16){ - $zx = ($z + $x); - for($y = 0; $y < 4096; $y += 256){ - $result{$i} = $array{$y + $zx}; + $zM = $x + 256; + for($z = $x; $z < $zM; $z += 16){ + $yM = $z + 4096; + for($y = $z; $y < $yM; $y += 256){ + $result{$i} = $array{$y}; ++$i; } } @@ -51,21 +54,27 @@ class ChunkUtils{ * Re-orders a nibble array (YZX -> XZY and vice versa) * * @param string $array length 2048 + * @param string $commonValue length 1 common value to fill the default array with and to expect, may improve sort time * * @return string length 2048 */ - public static final function reorderNibbleArray(string $array) : string{ - $result = str_repeat("\x00", 2048); + public static final function reorderNibbleArray(string $array, string $commonValue = "\x00") : string{ + $result = str_repeat($commonValue, 2048); $i = 0; for($x = 0; $x < 8; ++$x){ for($z = 0; $z < 16; ++$z){ $zx = (($z << 3) | $x); for($y = 0; $y < 8; ++$y){ $j = (($y << 8) | $zx); - $i1 = ord($array{$j}); - $i2 = ord($array{$j | 0x80}); - $result{$i} = chr(($i2 << 4) | ($i1 & 0x0f)); - $result{$i | 0x80} = chr(($i1 >> 4) | ($i2 & 0xf0)); + $j80 = ($j | 0x80); + if($array{$j} === $commonValue and $array{$j80} === $commonValue){ + //values are already filled + }else{ + $i1 = ord($array{$j}); + $i2 = ord($array{$j80}); + $result{$i} = chr(($i2 << 4) | ($i1 & 0x0f)); + $result{$i | 0x80} = chr(($i1 >> 4) | ($i2 & 0xf0)); + } $i++; } } diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index bf4a309a5..111c7f6a0 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -60,7 +60,7 @@ class Anvil extends McRegion{ "Y" => new ByteTag("Y", $y), "Blocks" => new ByteArrayTag("Blocks", ChunkUtils::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currently always XZY "Data" => new ByteArrayTag("Data", ChunkUtils::reorderNibbleArray($subChunk->getBlockDataArray())), - "SkyLight" => new ByteArrayTag("SkyLight", ChunkUtils::reorderNibbleArray($subChunk->getSkyLightArray())), + "SkyLight" => new ByteArrayTag("SkyLight", ChunkUtils::reorderNibbleArray($subChunk->getSkyLightArray(), "\xff")), "BlockLight" => new ByteArrayTag("BlockLight", ChunkUtils::reorderNibbleArray($subChunk->getBlockLightArray())) ]); } @@ -118,7 +118,7 @@ class Anvil extends McRegion{ $subChunks[$subChunk->Y->getValue()] = new SubChunk( ChunkUtils::reorderByteArray($subChunk->Blocks->getValue()), ChunkUtils::reorderNibbleArray($subChunk->Data->getValue()), - ChunkUtils::reorderNibbleArray($subChunk->SkyLight->getValue()), + ChunkUtils::reorderNibbleArray($subChunk->SkyLight->getValue(), "\xff"), ChunkUtils::reorderNibbleArray($subChunk->BlockLight->getValue()) ); }