public function __construct(LevelProvider $level, $regionX, $regionZ) { $this->x = $regionX; $this->z = $regionZ; $this->levelProvider = $level; $this->filePath = $this->levelProvider->getPath() . "region/r.{$regionX}.{$regionZ}.mcr"; $exists = file_exists($this->filePath); touch($this->filePath); $this->filePointer = fopen($this->filePath, "r+b"); stream_set_read_buffer($this->filePointer, 1024 * 16); //16KB stream_set_write_buffer($this->filePointer, 1024 * 16); //16KB if (!$exists) { $this->createBlank(); } else { $this->loadLocationTable(); } }
public function doChunkGarbageCollection() { $this->timings->doChunkGC->startTiming(); $X = null; $Z = null; foreach ($this->chunks as $index => $chunk) { if (!isset($this->unloadQueue[$index]) and (!isset($this->usedChunks[$index]) or count($this->usedChunks[$index]) === 0)) { if (PHP_INT_SIZE === 8) { $X = $index >> 32 << 32 >> 32; $Z = ($index & 4294967295.0) << 32 >> 32; } else { list($X, $Z) = explode(":", $index); $X = (int) $X; $Z = (int) $Z; } if (!$this->isSpawnChunk($X, $Z)) { $this->unloadChunkRequest($X, $Z, true); } } } foreach ($this->provider->getLoadedChunks() as $chunk) { if (!isset($this->chunks[PHP_INT_SIZE === 8 ? ($chunk->getX() & 4294967295.0) << 32 | $chunk->getZ() & 4294967295.0 : $chunk->getX() . ":" . $chunk->getZ()])) { $this->provider->unloadChunk($chunk->getX(), $chunk->getZ(), false); } } $this->provider->doGarbageCollection(); $this->timings->doChunkGC->stopTiming(); }
public function doChunkGarbageCollection() { $this->timings->doChunkGC->startTiming(); $X = null; $Z = null; foreach ($this->chunks as $index => $chunk) { if (!isset($this->unloadQueue[$index]) and (!isset($this->usedChunks[$index]) or count($this->usedChunks[$index]) === 0)) { Level::getXZ($index, $X, $Z); if (!$this->isSpawnChunk($X, $Z)) { $this->unloadChunkRequest($X, $Z, true); } } } foreach ($this->provider->getLoadedChunks() as $chunk) { if (!isset($this->chunks[Level::chunkHash($chunk->getX(), $chunk->getZ())])) { $this->provider->unloadChunk($chunk->getX(), $chunk->getZ(), false); } } $this->provider->doGarbageCollection(); $this->timings->doChunkGC->stopTiming(); }
public function doChunkGarbageCollection() { $this->timings->doChunkGC->startTiming(); $X = null; $Z = null; foreach ($this->chunks as $index => $chunk) { if (!isset($this->usedChunks[$index])) { Level::getXZ($index, $X, $Z); $this->unloadChunkRequest($X, $Z, true); } } if (count($this->unloadQueue) > 0) { foreach ($this->unloadQueue as $index => $time) { Level::getXZ($index, $X, $Z); if ($this->getAutoSave()) { $this->provider->saveChunk($X, $Z); } //If the chunk can't be unloaded, it stays on the queue if ($this->unloadChunk($X, $Z, true)) { unset($this->unloadQueue[$index]); } } } foreach ($this->usedChunks as $i => $c) { if (count($c) === 0) { Level::getXZ($i, $X, $Z); if (!$this->isSpawnChunk($X, $Z)) { if ($this->getAutoSave()) { $this->provider->saveChunk($X, $Z); } $this->unloadChunk($X, $Z, true); } } } $this->timings->doChunkGC->stopTiming(); }
/** * @param string $data * @param LevelProvider $provider * * @return Chunk */ public static function fromBinary($data, LevelProvider $provider = null) { try { $chunkX = PHP_INT_SIZE === 8 ? unpack("V", substr($data, 0, 4))[1] << 32 >> 32 : unpack("V", substr($data, 0, 4))[1]; $chunkZ = PHP_INT_SIZE === 8 ? unpack("V", substr($data, 4, 4))[1] << 32 >> 32 : unpack("V", substr($data, 4, 4))[1]; $chunkData = substr($data, 8, -1); $flags = ord(substr($data, -1)); $entities = null; $tiles = null; if ($provider instanceof LevelDB) { $nbt = new NBT(NBT::LITTLE_ENDIAN); $entityData = $provider->getDatabase()->get(substr($data, 0, 8) . "2"); if ($entityData !== false and strlen($entityData) > 0) { $nbt->read($entityData, true); $entities = $nbt->getData(); if (!is_array($entities)) { $entities = [$entities]; } } $tileData = $provider->getDatabase()->get(substr($data, 0, 8) . "1"); if ($tileData !== false and strlen($tileData) > 0) { $nbt->read($tileData, true); $tiles = $nbt->getData(); if (!is_array($tiles)) { $tiles = [$tiles]; } } } $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, $chunkData, $entities, $tiles); if ($flags & 0x1) { $chunk->setGenerated(); } if ($flags & 0x2) { $chunk->setPopulated(); } return $chunk; } catch (\Exception $e) { return null; } }
public function doChunkGarbageCollection() { $this->timings->doChunkGC->startTiming(); $X = \null; $Z = \null; foreach ($this->chunks as $index => $chunk) { if (!isset($this->unloadQueue[$index]) and (!isset($this->usedChunks[$index]) or \count($this->usedChunks[$index]) === 0)) { $X = $index >> 32 << 32 >> 32; $Z = ($index & 0xffffffff) << 32 >> 32; if (!$this->isSpawnChunk($X, $Z)) { $this->unloadChunkRequest($X, $Z, \true); } } } foreach ($this->provider->getLoadedChunks() as $chunk) { if (!isset($this->chunks[($chunk->getX() & 0xffffffff) << 32 | $chunk->getZ() & 0xffffffff])) { $this->provider->unloadChunk($chunk->getX(), $chunk->getZ(), \false); } } $this->provider->doGarbageCollection(); $this->timings->doChunkGC->stopTiming(); }
/** * @param string $data * @param LevelProvider $provider * * @return Chunk */ public static function fromBinary($data, LevelProvider $provider = \null) { try { $chunkX = \unpack("V", \substr($data, 0, 4))[1]; $chunkZ = \unpack("V", \substr($data, 4, 4))[1]; $chunkData = \substr($data, 8, -1); $flags = \ord(\substr($data, -1)); $entities = \null; $tiles = \null; $extraData = []; if ($provider instanceof LevelDB) { $nbt = new NBT(NBT::LITTLE_ENDIAN); $entityData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_ENTITIES); if ($entityData !== \false and \strlen($entityData) > 0) { $nbt->read($entityData, \true); $entities = $nbt->getData(); if (!\is_array($entities)) { $entities = [$entities]; } } $tileData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_TILES); if ($tileData !== \false and \strlen($tileData) > 0) { $nbt->read($tileData, \true); $tiles = $nbt->getData(); if (!\is_array($tiles)) { $tiles = [$tiles]; } } $tileData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_EXTRA_DATA); if ($tileData !== \false and \strlen($tileData) > 0) { $stream = new BinaryStream($tileData); $count = $stream->getInt(); for ($i = 0; $i < $count; ++$i) { $key = $stream->getInt(); $value = $stream->getShort(\false); $extraData[$key] = $value; } } } $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, $chunkData, $entities, $tiles); if ($flags & 0x1) { $chunk->setGenerated(); } if ($flags & 0x2) { $chunk->setPopulated(); } if ($flags & 0x4) { $chunk->setLightPopulated(); } return $chunk; } catch (\Exception $e) { return \null; } }
public function doChunkGarbageCollection() { $this->timings->doChunkGC->startTiming(); $X = \null; $Z = \null; foreach ($this->chunks as $index => $chunk) { if (!isset($this->unloadQueue[$index]) and (!isset($this->usedChunks[$index]) or \count($this->usedChunks[$index]) === 0)) { list($X, $Z) = \explode(":", $index); $X = (int) $X; $Z = (int) $Z; if (!$this->isSpawnChunk($X, $Z)) { $this->unloadChunkRequest($X, $Z, \true); } } } foreach ($this->provider->getLoadedChunks() as $chunk) { if (!isset($this->chunks[$chunk->getX() . ":" . $chunk->getZ()])) { $this->provider->unloadChunk($chunk->getX(), $chunk->getZ(), \false); } } $this->provider->doGarbageCollection(); $this->timings->doChunkGC->stopTiming(); }