Some consistency would be nice... fixed inconsistency between block light and sky light, always use Mojang order

This commit is contained in:
Dylan K. Taylor 2017-01-03 19:15:23 +00:00
parent 8a29e77f5e
commit e2dc1a3bc6
6 changed files with 69 additions and 62 deletions

View File

@ -59,14 +59,6 @@ class EmptySubChunk extends SubChunk{
return false; return false;
} }
public function getBlockSkyLight(int $x, int $y, int $z) : int{
return 15;
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
return false;
}
public function getBlockLight(int $x, int $y, int $z) : int{ public function getBlockLight(int $x, int $y, int $z) : int{
return 0; return 0;
} }
@ -75,6 +67,14 @@ class EmptySubChunk extends SubChunk{
return false; return false;
} }
public function getBlockSkyLight(int $x, int $y, int $z) : int{
return 15;
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
return false;
}
public function getBlockIdColumn(int $x, int $z) : string{ public function getBlockIdColumn(int $x, int $z) : string{
return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
} }

View File

@ -281,7 +281,7 @@ class GenericChunk implements Chunk{
for($z = 0; $z < 16; ++$z){ for($z = 0; $z < 16; ++$z){
$heightMap = $this->getHeightMap($x, $z); $heightMap = $this->getHeightMap($x, $z);
$y = min($this->getHighestSubChunkIndex() << 4, $heightMap); $y = min(($this->getHighestSubChunkIndex() + 1) << 4, $heightMap);
for(; $y > $heightMap; --$y){ for(; $y > $heightMap; --$y){
$this->setBlockSkyLight($x, $y, $z, 15); $this->setBlockSkyLight($x, $y, $z, 15);
@ -652,12 +652,7 @@ class GenericChunk implements Chunk{
$subChunks = []; $subChunks = [];
$count = $stream->getByte(); $count = $stream->getByte();
for($y = 0; $y < $count; ++$y){ for($y = 0; $y < $count; ++$y){
$subChunks[$stream->getByte()] = new SubChunk( $subChunks[$stream->getByte()] = SubChunk::fastDeserialize($stream->get(10240));
$stream->get(4096), //blockIds
$stream->get(2048), //blockData
$stream->get(2048), //skyLight
$stream->get(2048) //blockLight
);
} }
$heightMap = array_values(unpack("C*", $stream->get(256))); $heightMap = array_values(unpack("C*", $stream->get(256)));
$biomeIds = $stream->get(256); $biomeIds = $stream->get(256);

View File

@ -39,11 +39,11 @@ class SubChunk{
} }
} }
public function __construct(string $ids = "", string $data = "", string $blockLight = "", string $skyLight = ""){ public function __construct(string $ids = "", string $data = "", string $skyLight = "", string $blockLight = ""){
self::assignData($this->ids, $ids, 4096); self::assignData($this->ids, $ids, 4096);
self::assignData($this->data, $data, 2048); self::assignData($this->data, $data, 2048);
self::assignData($this->blockLight, $blockLight, 2048);
self::assignData($this->skyLight, $skyLight, 2048); self::assignData($this->skyLight, $skyLight, 2048);
self::assignData($this->blockLight, $blockLight, 2048);
} }
public function isEmpty() : bool{ public function isEmpty() : bool{
@ -115,26 +115,6 @@ class SubChunk{
return $changed; return $changed;
} }
public function getBlockSkyLight(int $x, int $y, int $z) : int{
$byte = ord($this->skyLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){
return $byte & 0x0f;
}else{
return $byte >> 4;
}
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) + ($z << 3) + ($y >> 1);
$byte = ord($this->skyLight{$i});
if(($y & 1) === 0){
$this->skyLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
}else{
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
}
return true;
}
public function getBlockLight(int $x, int $y, int $z) : int{ public function getBlockLight(int $x, int $y, int $z) : int{
$byte = ord($this->blockLight{($x << 7) + ($z << 3) + ($y >> 1)}); $byte = ord($this->blockLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){ if(($y & 1) === 0){
@ -155,6 +135,26 @@ class SubChunk{
return true; return true;
} }
public function getBlockSkyLight(int $x, int $y, int $z) : int{
$byte = ord($this->skyLight{($x << 7) + ($z << 3) + ($y >> 1)});
if(($y & 1) === 0){
return $byte & 0x0f;
}else{
return $byte >> 4;
}
}
public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{
$i = ($x << 7) + ($z << 3) + ($y >> 1);
$byte = ord($this->skyLight{$i});
if(($y & 1) === 0){
$this->skyLight{$i} = chr(($byte & 0xf0) | ($level & 0x0f));
}else{
$this->skyLight{$i} = chr((($level & 0x0f) << 4) | ($byte & 0x0f));
}
return true;
}
public function getHighestBlockAt(int $x, int $z) : int{ public function getHighestBlockAt(int $x, int $z) : int{
for($y = 15; $y >= 0; --$y){ for($y = 15; $y >= 0; --$y){
if($this->ids{($x << 8) | ($z << 4) | $y} !== "\x00"){ if($this->ids{($x << 8) | ($z << 4) | $y} !== "\x00"){
@ -191,23 +191,35 @@ class SubChunk{
return $this->data; return $this->data;
} }
public function getBlockLightArray() : string{
assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight));
return $this->blockLight;
}
public function getSkyLightArray() : string{ public function getSkyLightArray() : string{
assert(strlen($this->skyLight) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($this->skyLight)); assert(strlen($this->skyLight) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($this->skyLight));
return $this->skyLight; return $this->skyLight;
} }
public function getBlockLightArray() : string{
assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight));
return $this->blockLight;
}
public function networkSerialize() : string{ public function networkSerialize() : string{
// storage version, ids, data, skylight, blocklight // storage version, ids, data, skylight, blocklight
return "\x00" . $this->ids . $this->data . $this->skyLight . $this->blockLight; return "\x00" . $this->ids . $this->data . $this->skyLight . $this->blockLight;
} }
public function fastSerialize() : string{ public function fastSerialize() : string{
// ids, data, skylight, blocklight return
return $this->ids . $this->data . $this->skyLight . $this->blockLight; $this->ids .
$this->data .
$this->skyLight .
$this->blockLight;
}
public static function fastDeserialize(string $data) : SubChunk{
return new SubChunk(
substr($data, 0, 4096), //ids
substr($data, 4096, 2048), //data
substr($data, 6144, 2048), //sky light
substr($data, 8192, 2048) //block light
);
} }
} }

View File

@ -61,8 +61,8 @@ class Anvil extends McRegion{
"Y" => new ByteTag("Y", $y), "Y" => new ByteTag("Y", $y),
"Blocks" => new ByteArrayTag("Blocks", GenericChunk::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currrently always XZY "Blocks" => new ByteArrayTag("Blocks", GenericChunk::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currrently always XZY
"Data" => new ByteArrayTag("Data", GenericChunk::reorderNibbleArray($subChunk->getBlockDataArray())), "Data" => new ByteArrayTag("Data", GenericChunk::reorderNibbleArray($subChunk->getBlockDataArray())),
"BlockLight" => new ByteArrayTag("BlockLight", GenericChunk::reorderNibbleArray($subChunk->getBlockLightArray())), "SkyLight" => new ByteArrayTag("SkyLight", GenericChunk::reorderNibbleArray($subChunk->getSkyLightArray())),
"SkyLight" => new ByteArrayTag("SkyLight", GenericChunk::reorderNibbleArray($subChunk->getSkyLightArray())) "BlockLight" => new ByteArrayTag("BlockLight", GenericChunk::reorderNibbleArray($subChunk->getBlockLightArray()))
]); ]);
} }
@ -119,8 +119,8 @@ class Anvil extends McRegion{
$subChunks[$subChunk->Y->getValue()] = new SubChunk( $subChunks[$subChunk->Y->getValue()] = new SubChunk(
GenericChunk::reorderByteArray($subChunk->Blocks->getValue()), GenericChunk::reorderByteArray($subChunk->Blocks->getValue()),
GenericChunk::reorderNibbleArray($subChunk->Data->getValue()), GenericChunk::reorderNibbleArray($subChunk->Data->getValue()),
GenericChunk::reorderNibbleArray($subChunk->BlockLight->getValue()), GenericChunk::reorderNibbleArray($subChunk->SkyLight->getValue()),
GenericChunk::reorderNibbleArray($subChunk->SkyLight->getValue()) GenericChunk::reorderNibbleArray($subChunk->BlockLight->getValue())
); );
} }
} }

View File

@ -64,8 +64,8 @@ class McRegion extends BaseLevelProvider{
$ids = ""; $ids = "";
$data = ""; $data = "";
$blockLight = "";
$skyLight = ""; $skyLight = "";
$blockLight = "";
$subChunks = $chunk->getSubChunks(); $subChunks = $chunk->getSubChunks();
for($x = 0; $x < 16; ++$x){ for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){ for($z = 0; $z < 16; ++$z){
@ -73,8 +73,8 @@ class McRegion extends BaseLevelProvider{
$subChunk = $subChunks[$y]; $subChunk = $subChunks[$y];
$ids .= $subChunk->getBlockIdColumn($x, $z); $ids .= $subChunk->getBlockIdColumn($x, $z);
$data .= $subChunk->getBlockDataColumn($x, $z); $data .= $subChunk->getBlockDataColumn($x, $z);
$blockLight .= $subChunk->getBlockLightColumn($x, $z);
$skyLight .= $subChunk->getSkyLightColumn($x, $z); $skyLight .= $subChunk->getSkyLightColumn($x, $z);
$blockLight .= $subChunk->getBlockLightColumn($x, $z);
} }
} }
} }
@ -138,8 +138,8 @@ class McRegion extends BaseLevelProvider{
$subChunks = []; $subChunks = [];
$fullIds = isset($chunk->Blocks) ? $chunk->Blocks->getValue() : str_repeat("\x00", 32768); $fullIds = isset($chunk->Blocks) ? $chunk->Blocks->getValue() : str_repeat("\x00", 32768);
$fullData = isset($chunk->Data) ? $chunk->Data->getValue() : ($half = str_repeat("\x00", 16384)); $fullData = isset($chunk->Data) ? $chunk->Data->getValue() : ($half = str_repeat("\x00", 16384));
$fullBlockLight = isset($chunk->BlockLight) ? $chunk->BlockLight->getValue() : $half;
$fullSkyLight = isset($chunk->SkyLight) ? $chunk->SkyLight->getValue() : str_repeat("\xff", 16384); $fullSkyLight = isset($chunk->SkyLight) ? $chunk->SkyLight->getValue() : str_repeat("\xff", 16384);
$fullBlockLight = isset($chunk->BlockLight) ? $chunk->BlockLight->getValue() : $half;
for($y = 0; $y < 8; ++$y){ for($y = 0; $y < 8; ++$y){
$offset = ($y << 4); $offset = ($y << 4);
@ -154,19 +154,19 @@ class McRegion extends BaseLevelProvider{
$data .= substr($fullData, $offset, 8); $data .= substr($fullData, $offset, 8);
$offset += 64; $offset += 64;
} }
$blockLight = "";
$offset = ($y << 3);
for($i = 0; $i < 256; ++$i){
$blockLight .= substr($fullBlockLight, $offset, 8);
$offset += 64;
}
$skyLight = ""; $skyLight = "";
$offset = ($y << 3); $offset = ($y << 3);
for($i = 0; $i < 256; ++$i){ for($i = 0; $i < 256; ++$i){
$skyLight .= substr($fullSkyLight, $offset, 8); $skyLight .= substr($fullSkyLight, $offset, 8);
$offset += 64; $offset += 64;
} }
$subChunks[$y] = new SubChunk($ids, $data, $blockLight, $skyLight); $blockLight = "";
$offset = ($y << 3);
for($i = 0; $i < 256; ++$i){
$blockLight .= substr($fullBlockLight, $offset, 8);
$offset += 64;
}
$subChunks[$y] = new SubChunk($ids, $data, $skyLight, $blockLight);
} }
if(isset($chunk->BiomeColors)){ if(isset($chunk->BiomeColors)){

View File

@ -65,8 +65,8 @@ class PMAnvil extends Anvil{
"Y" => new ByteTag("Y", $y), "Y" => new ByteTag("Y", $y),
"Blocks" => new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()), "Blocks" => new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()),
"Data" => new ByteArrayTag("Data", $subChunk->getBlockDataArray()), "Data" => new ByteArrayTag("Data", $subChunk->getBlockDataArray()),
"BlockLight" => new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray()), "SkyLight" => new ByteArrayTag("SkyLight", $subChunk->getSkyLightArray()),
"SkyLight" => new ByteArrayTag("SkyLight", $subChunk->getSkyLightArray()) "BlockLight" => new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray())
]); ]);
} }
@ -123,8 +123,8 @@ class PMAnvil extends Anvil{
$subChunks[$subChunk->Y->getValue()] = new SubChunk( $subChunks[$subChunk->Y->getValue()] = new SubChunk(
$subChunk->Blocks->getValue(), $subChunk->Blocks->getValue(),
$subChunk->Data->getValue(), $subChunk->Data->getValue(),
$subChunk->BlockLight->getValue(), $subChunk->SkyLight->getValue(),
$subChunk->SkyLight->getValue() $subChunk->BlockLight->getValue()
); );
} }
} }