mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-12 14:35:35 +00:00
RegionLoader: Extract location table validation to separate function
This commit is contained in:
parent
f2404804d7
commit
3f66600271
@ -269,34 +269,56 @@ class RegionLoader{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack("N*", $headerRaw);
|
$data = unpack("N*", $headerRaw);
|
||||||
/** @var int[] $usedOffsets */
|
|
||||||
$usedOffsets = [];
|
|
||||||
for($i = 0; $i < 1024; ++$i){
|
for($i = 0; $i < 1024; ++$i){
|
||||||
$index = $data[$i + 1];
|
$index = $data[$i + 1];
|
||||||
$offset = $index >> 8;
|
$offset = $index >> 8;
|
||||||
$timestamp = $data[$i + 1025];
|
$timestamp = $data[$i + 1025];
|
||||||
if($offset !== 0){
|
|
||||||
self::getChunkCoords($i, $x, $z);
|
|
||||||
$fileOffset = $offset << 12;
|
|
||||||
|
|
||||||
fseek($this->filePointer, $fileOffset);
|
if($offset === 0){
|
||||||
if(fgetc($this->filePointer) === false){ //Try and read from the location
|
$this->locationTable[$i] = new RegionLocationTableEntry(0, 0, 0);
|
||||||
throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset");
|
}else{
|
||||||
}elseif(isset($usedOffsets[$offset])){
|
$this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp);
|
||||||
self::getChunkCoords($usedOffsets[$offset], $existingX, $existingZ);
|
$this->bumpNextFreeSector($this->locationTable[$i]);
|
||||||
throw new CorruptedRegionException("Found two chunk offsets (chunk1: x=$existingX,z=$existingZ, chunk2: x=$x,z=$z) pointing to the file location $fileOffset");
|
|
||||||
}else{
|
|
||||||
$usedOffsets[$offset] = $i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp);
|
|
||||||
$this->bumpNextFreeSector($this->locationTable[$i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->checkLocationTableValidity();
|
||||||
|
|
||||||
fseek($this->filePointer, 0);
|
fseek($this->filePointer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws CorruptedRegionException
|
||||||
|
*/
|
||||||
|
private function checkLocationTableValidity() : void{
|
||||||
|
/** @var int[] $usedOffsets */
|
||||||
|
$usedOffsets = [];
|
||||||
|
|
||||||
|
for($i = 0; $i < 1024; ++$i){
|
||||||
|
$entry = $this->locationTable[$i];
|
||||||
|
if($entry->isNull()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::getChunkCoords($i, $x, $z);
|
||||||
|
$offset = $entry->getFirstSector();
|
||||||
|
$fileOffset = $offset << 12;
|
||||||
|
|
||||||
|
//TODO: more validity checks
|
||||||
|
|
||||||
|
fseek($this->filePointer, $fileOffset);
|
||||||
|
if(fgetc($this->filePointer) === false){ //Try and read from the location
|
||||||
|
throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset");
|
||||||
|
}
|
||||||
|
if(isset($usedOffsets[$offset])){
|
||||||
|
self::getChunkCoords($usedOffsets[$offset], $existingX, $existingZ);
|
||||||
|
throw new CorruptedRegionException("Found two chunk offsets (chunk1: x=$existingX,z=$existingZ, chunk2: x=$x,z=$z) pointing to the file location $fileOffset");
|
||||||
|
}
|
||||||
|
$usedOffsets[$offset] = $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function writeLocationTable() : void{
|
private function writeLocationTable() : void{
|
||||||
$write = [];
|
$write = [];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user