/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if ($currentTick % 200 === 0) { $this->sendTime(); } $this->unloadChunks(); $X = null; $Z = null; //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[PHP_INT_SIZE === 8 ? ($block->x & 0xfffffff) << 35 | ($block->y & 0x7f) << 28 | $block->z & 0xfffffff : $block->x . ":" . $block->y . ":" . $block->z]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { //Timings::$tickTileEntityTimer->startTiming(); foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } //Timings::$tickTileEntityTimer->stopTiming(); } $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); if (count($this->changedCount) > 0) { if (count($this->players) > 0) { foreach ($this->changedCount as $index => $mini) { for ($Y = 0; $Y < 8; ++$Y) { if (($mini & 1 << $Y) === 0) { continue; } if (count($this->changedBlocks[$index][$Y]) < 256) { continue; } else { $X = null; $Z = null; 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; } foreach ($this->getUsingChunk($X, $Z) as $p) { $p->unloadChunk($X, $Z); } unset($this->changedBlocks[$index][$Y]); } } } $this->changedCount = []; if (count($this->changedBlocks) > 0) { foreach ($this->changedBlocks as $index => $mini) { foreach ($mini as $blocks) { /** @var Block $b */ foreach ($blocks as $b) { $pk = new UpdateBlockPacket(); $pk->x = $b->x; $pk->y = $b->y; $pk->z = $b->z; $pk->block = $b->getId(); $pk->meta = $b->getDamage(); Server::broadcastPacket($this->getUsingChunk($b->x >> 4, $b->z >> 4), $pk); } } } $this->changedBlocks = []; } } else { $this->changedCount = []; $this->changedBlocks = []; } } $this->processChunkRequest(); foreach ($this->moveToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new MoveEntityPacket(); $pk->entities = $entry; Server::broadcastPacket($this->getUsingChunk($chunkX, $chunkZ), $pk); } $this->moveToSend = []; foreach ($this->motionToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new SetEntityMotionPacket(); $pk->entities = $entry; Server::broadcastPacket($this->getUsingChunk($chunkX, $chunkZ), $pk); } $this->motionToSend = []; $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if ($currentTick % 200 === 0) { $this->sendTime(); } if (count($this->changedCount) > 0) { if (count($this->players) > 0) { foreach ($this->changedCount as $index => $mini) { for ($Y = 0; $Y < 8; ++$Y) { if (($mini & 1 << $Y) === 0) { continue; } if (count($this->changedBlocks[$index][$Y]) < 582) { //Optimal value, calculated using the relation between minichunks and single packets continue; } else { $X = null; $Z = null; Level::getXZ($index, $X, $Z); foreach ($this->getUsingChunk($X, $Z) as $p) { $p->unloadChunk($X, $Z); } unset($this->changedBlocks[$index][$Y]); } } } $this->changedCount = []; if (count($this->changedBlocks) > 0) { foreach ($this->changedBlocks as $index => $mini) { foreach ($mini as $blocks) { /** @var Block $b */ foreach ($blocks as $b) { $pk = new UpdateBlockPacket(); $pk->x = $b->x; $pk->y = $b->y; $pk->z = $b->z; $pk->block = $b->getID(); $pk->meta = $b->getDamage(); foreach ($this->getUsingChunk($b->x >> 4, $b->z >> 4) as $player) { $player->dataPacket($pk); } } } } $this->changedBlocks = []; } } else { $this->changedCount = []; $this->changedBlocks = []; } } $X = null; $Z = null; //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update //if(count($this->updateEntities) > 0){ //Timings::$tickEntityTimer->startTiming(); foreach ($this->entities as $id => $entity) { if ($entity->onUpdate() !== true) { unset($this->updateEntities[$id]); } } //Timings::$tickEntityTimer->stopTiming(); //} $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { //Timings::$tickTileEntityTimer->startTiming(); foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } //Timings::$tickTileEntityTimer->stopTiming(); } $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); $this->processChunkRequest(); $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if (++$this->sendTimeTicker === 200) { $this->sendTime(); $this->sendTimeTicker = 0; } $this->unloadChunks(); //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); if (count($this->changedBlocks) > 0) { if (count($this->players) > 0) { foreach ($this->changedBlocks as $index => $blocks) { unset($this->chunkCache[$index]); Level::getXZ($index, $chunkX, $chunkZ); if (count($blocks) > 512) { $chunk = $this->getChunk($chunkX, $chunkZ); foreach ($this->getChunkPlayers($chunkX, $chunkZ) as $p) { $p->onChunkChanged($chunk); } } else { $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks, UpdateBlockPacket::FLAG_ALL); } } } else { $this->chunkCache = []; } $this->changedBlocks = []; } $this->processChunkRequest(); if ($this->sleepTicks > 0 and --$this->sleepTicks <= 0) { $this->checkSleep(); } foreach ($this->moveToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new MoveEntityPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->moveToSend = []; foreach ($this->motionToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new SetEntityMotionPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->motionToSend = []; foreach ($this->chunkPackets as $index => $entries) { Level::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if (count($chunkPlayers) > 0) { foreach ($entries as $pk) { Server::broadcastPacket($chunkPlayers, $pk); } } } $this->chunkPackets = []; $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if (++$this->sendTimeTicker === 200) { $this->sendTime(); $this->sendTimeTicker = 0; } if ($this->weatherEnabled === true) { $randomDayTime = mt_rand(self::TIME_DAY, self::TIME_SUNSET); $randomNightTime = mt_rand(self::TIME_NIGHT, self::TIME_SUNRISE); if ($this->weatherExecute === true && ($this->time >= $randomDayTime && $this->time <= $randomDayTime + 100) || $this->time >= $randomNightTime && $this->time <= $randomNightTime + 100 && ($this->isRaining() || $this->isThundering()) === false) { //If is executed recalculate the chance of weather $this->randomWeather = mt_rand(0, 150); $this->weatherExecute = false; } elseif ($this->weatherExecute === false && ($this->time >= $randomDayTime && $this->time <= $randomDayTime + 100) || $this->time >= $randomNightTime && $this->time <= $randomNightTime + 100 && ($this->isRaining() || $this->isThundering()) === false) { $this->randomWeather = mt_rand(0, 150); } $this->rainTime--; if ($this->rainTime <= 0) { $this->setRaining(!$this->raining); } else { if ($this->time >= $randomDayTime && $this->time <= $randomDayTime + 100 || $this->time >= $randomNightTime && $this->time <= $randomNightTime + 100) { switch ($this->randomWeather) { case 20: case 30: $this->setRaining(true); $this->weatherExecute = true; break; default: $this->weatherExecute = false; } } } $this->thunderTime--; if ($this->thunderTime <= 0) { $this->setThundering(!$this->thundering); } else { if ($this->time >= $randomDayTime && $this->time <= $randomDayTime + 100 || $this->time >= $randomNightTime && $this->time <= $randomNightTime + 100) { switch ($this->randomWeather) { case 5: case 10: $this->setThundering(true); $this->setRaining(true); $this->weatherExecute = true; break; default: $this->weatherExecute = false; } } } if (($this->isThundering() && $this->isRaining()) === true) { //Random thunders foreach ($this->getPlayers() as $p) { $x = $p->getX() + rand(-100, 100); $y = $p->getY() + rand(20, 50); $z = $p->getZ() + rand(-100, 100); $caseLightning = mt_rand(0, 500); switch ((int) $caseLightning) { case 15: case 50: $this->addLightning($x, $y, $z, $p); } } } } if ($this->getTime() >= self::TIME_FULL) { //Prevent to go out of 24000 ticks $this->setTime(self::TIME_DAY); } $this->unloadChunks(); //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); //Do Redstone updates if ($this->server->getProperty("redstone.enable", true)) { $this->timings->doTickPending->startTiming(); while ($this->updateRedstoneQueue->count() > 0 and $this->updateRedstoneQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateRedstoneQueue->extract()["data"]); $hash = Level::blockHash($block->x, $block->y, $block->z); $type = $this->updateRedstoneQueueIndex[$hash]['type']; $power = $this->updateRedstoneQueueIndex[$hash]['power']; unset($this->updateRedstoneQueueIndex[$hash]); $block->onRedstoneUpdate($type, $power); } $this->timings->doTickPending->stopTiming(); } $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); if ($currentTick % 2 === 0) { $this->tickChunks(); } $this->timings->doTickTiles->stopTiming(); if (count($this->changedBlocks) > 0) { if (count($this->players) > 0) { foreach ($this->changedBlocks as $index => $blocks) { unset($this->chunkCache[$index]); Level::getXZ($index, $chunkX, $chunkZ); if (count($blocks) > 512) { $chunk = $this->getChunk($chunkX, $chunkZ); foreach ($this->getChunkPlayers($chunkX, $chunkZ) as $p) { $p->onChunkChanged($chunk); } } else { $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks, UpdateBlockPacket::FLAG_ALL); } } } else { $this->chunkCache = []; } $this->changedBlocks = []; } $this->processChunkRequest(); if ($this->sleepTicks > 0 and --$this->sleepTicks <= 0) { $this->checkSleep(); } foreach ($this->moveToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new MoveEntityPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->moveToSend = []; foreach ($this->motionToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); $pk = new SetEntityMotionPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->motionToSend = []; foreach ($this->chunkPackets as $index => $entries) { Level::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if (count($chunkPlayers) > 0) { foreach ($entries as $pk) { Server::broadcastPacket($chunkPlayers, $pk); } } } $this->chunkPackets = []; $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if (++$this->sendTimeTicker === 200) { $this->sendTime(); $this->sendTimeTicker = 0; } $this->unloadChunks(); $X = null; $Z = null; //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { //Timings::$tickTileEntityTimer->startTiming(); foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } //Timings::$tickTileEntityTimer->stopTiming(); } $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); if (count($this->changedBlocks) > 0) { if (count($this->players) > 0) { foreach ($this->changedBlocks as $index => $blocks) { unset($this->chunkCache[$index]); Level::getXZ($index, $X, $Z); if (count($blocks) > 512) { foreach ($this->getUsingChunk($X, $Z) as $p) { $p->unloadChunk($X, $Z); } } else { $this->sendBlocks($this->getUsingChunk($X, $Z), $blocks, UpdateBlockPacket::FLAG_ALL); } } } else { $this->chunkCache = []; } $this->changedBlocks = []; } $this->processChunkRequest(); if ($this->sleepTicks > 0 and --$this->sleepTicks <= 0) { $this->checkSleep(); } $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick($currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); if (++$this->sendTimeTicker === 200) { $this->sendTime(); $this->sendTimeTicker = 0; } $this->unloadChunks(); //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[\PHP_INT_SIZE === 8 ? ($block->x & 0xfffffff) << 35 | ($block->y & 0x7f) << 28 | $block->z & 0xfffffff : $block->x . ":" . $block->y . ":" . $block->z]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update if (\count($this->updateTiles) > 0) { foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== \true) { unset($this->updateTiles[$id]); } } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); if (\count($this->changedBlocks) > 0) { if (\count($this->players) > 0) { foreach ($this->changedBlocks as $index => $blocks) { unset($this->chunkCache[$index]); if (\PHP_INT_SIZE === 8) { $chunkX = $index >> 32 << 32 >> 32; $chunkZ = ($index & 0xffffffff) << 32 >> 32; } else { list($chunkX, $chunkZ) = \explode(":", $index); $chunkX = (int) $chunkX; $chunkZ = (int) $chunkZ; } if (\count($blocks) > 512) { $chunk = $this->getChunk($chunkX, $chunkZ); foreach ($this->getChunkPlayers($chunkX, $chunkZ) as $p) { $p->onChunkChanged($chunk); } } else { $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks, UpdateBlockPacket::FLAG_ALL); } } } else { $this->chunkCache = []; } $this->changedBlocks = []; } $this->processChunkRequest(); if ($this->sleepTicks > 0 and --$this->sleepTicks <= 0) { $this->checkSleep(); } foreach ($this->moveToSend as $index => $entry) { if (\PHP_INT_SIZE === 8) { $chunkX = $index >> 32 << 32 >> 32; $chunkZ = ($index & 0xffffffff) << 32 >> 32; } else { list($chunkX, $chunkZ) = \explode(":", $index); $chunkX = (int) $chunkX; $chunkZ = (int) $chunkZ; } $pk = new MoveEntityPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->moveToSend = []; foreach ($this->motionToSend as $index => $entry) { if (\PHP_INT_SIZE === 8) { $chunkX = $index >> 32 << 32 >> 32; $chunkZ = ($index & 0xffffffff) << 32 >> 32; } else { list($chunkX, $chunkZ) = \explode(":", $index); $chunkX = (int) $chunkX; $chunkZ = (int) $chunkZ; } $pk = new SetEntityMotionPacket(); $pk->entities = $entry; $this->addChunkPacket($chunkX, $chunkZ, $pk); } $this->motionToSend = []; foreach ($this->chunkPackets as $index => $entries) { if (\PHP_INT_SIZE === 8) { $chunkX = $index >> 32 << 32 >> 32; $chunkZ = ($index & 0xffffffff) << 32 >> 32; } else { list($chunkX, $chunkZ) = \explode(":", $index); $chunkX = (int) $chunkX; $chunkZ = (int) $chunkZ; } $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if (\count($chunkPlayers) > 0) { foreach ($entries as $pk) { Server::broadcastPacket($chunkPlayers, $pk); } } } $this->chunkPackets = []; $this->timings->doTick->stopTiming(); }
/** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @param int $currentTick * * @return bool */ public function doTick(int $currentTick) { $this->timings->doTick->startTiming(); $this->checkTime(); $this->unloadChunks(); //Do block updates $this->timings->doTickPending->startTiming(); while ($this->updateQueue->count() > 0 and $this->updateQueue->current()["priority"] <= $currentTick) { $block = $this->getBlock($this->updateQueue->extract()["data"]); unset($this->updateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); $block->onUpdate(self::BLOCK_UPDATE_SCHEDULED); } $this->timings->doTickPending->stopTiming(); //Do Redstone updates if ($this->server->getProperty("redstone.enable", true)) { $this->timings->doTickRedstone->startTiming(); $Counter = 0; while ($this->updateRedstoneQueue->count() > 0 and $this->updateRedstoneQueue->current()["priority"] <= $currentTick) { $Counter++; $block = $this->getBlock($this->updateRedstoneQueue->extract()["data"]); $hash = Level::blockHash($block->x, $block->y, $block->z); $this->updateRedstoneQueueIndex[$hash] = array_values($this->updateRedstoneQueueIndex[$hash]); if (count($this->updateRedstoneQueueIndex[$hash]) == 1) { $type = $this->updateRedstoneQueueIndex[$hash][0]['type']; $power = $this->updateRedstoneQueueIndex[$hash][0]['power']; unset($this->updateRedstoneQueueIndex[$hash]); } else { $type = $this->updateRedstoneQueueIndex[$hash][0]['type']; $power = $this->updateRedstoneQueueIndex[$hash][0]['power']; unset($this->updateRedstoneQueueIndex[$hash][0]); } $this->server->getPluginManager()->callEvent($ev = new RedstoneBlockUpdateEvent($block)); //if(!$ev->isCancelled()){ $this->doRedstoneBlockUpdate($block, $type, $power, $hash); //$ev->getBlock() //} if ($Counter >= $this->server->getProperty("redstone.tick-limit", 2048)) { break; } } $this->timings->doTickRedstone->stopTiming(); } $this->timings->entityTick->startTiming(); //Update entities that need update Timings::$tickEntityTimer->startTiming(); foreach ($this->updateEntities as $id => $entity) { if ($entity->closed or !$entity->onUpdate($currentTick)) { unset($this->updateEntities[$id]); } } Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update if (count($this->updateTiles) > 0) { foreach ($this->updateTiles as $id => $tile) { if ($tile->onUpdate() !== true) { unset($this->updateTiles[$id]); } } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); if (count($this->changedBlocks) > 0) { if (count($this->players) > 0) { foreach ($this->changedBlocks as $index => $blocks) { unset($this->chunkCache[$index]); Level::getXZ($index, $chunkX, $chunkZ); if (count($blocks) > 512) { $chunk = $this->getChunk($chunkX, $chunkZ); foreach ($this->getChunkPlayers($chunkX, $chunkZ) as $p) { $p->onChunkChanged($chunk); } } else { $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks, UpdateBlockPacket::FLAG_ALL); } } } else { $this->chunkCache = []; } $this->changedBlocks = []; } $this->processChunkRequest(); if ($this->sleepTicks > 0 and --$this->sleepTicks <= 0) { $this->checkSleep(); } foreach ($this->moveToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); foreach ($entry as $e) { $pk = new MoveEntityPacket(); $pk->eid = $e[0]; $pk->x = $e[1]; $pk->y = $e[2]; $pk->z = $e[3]; $pk->yaw = $e[4]; $pk->headYaw = $e[5]; $pk->pitch = $e[6]; $this->addChunkPacket($chunkX, $chunkZ, $pk); } } $this->moveToSend = []; foreach ($this->motionToSend as $index => $entry) { Level::getXZ($index, $chunkX, $chunkZ); foreach ($entry as $entity) { $pk = new SetEntityMotionPacket(); $pk->eid = $entity[0]; $pk->motionX = $entity[1]; $pk->motionY = $entity[2]; $pk->motionZ = $entity[3]; $this->addChunkPacket($chunkX, $chunkZ, $pk); } } $this->motionToSend = []; foreach ($this->chunkPackets as $index => $entries) { Level::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if (count($chunkPlayers) > 0) { foreach ($entries as $pk) { Server::broadcastPacket($chunkPlayers, $pk); } } } $this->chunkPackets = []; #$this->generateWeather(); //TODO: TEST + REVERT $this->timings->doTick->stopTiming(); }
/** * * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. * * @return bool */ public function orderChunks() { if ($this->connected === false) { return false; } $radiusSquared = $this->viewDistance / M_PI; $radius = ceil(sqrt($radiusSquared)); $newOrder = []; $lastChunk = $this->usedChunks; $centerX = $this->x >> 4; $centerZ = $this->z >> 4; $generateQueue = new ReversePriorityQueue(); for ($X = -$radius; $X <= $radius; ++$X) { for ($Z = -$radius; $Z <= $radius; ++$Z) { $distance = $X * $X + $Z * $Z; if ($distance > $radiusSquared) { continue; } $chunkX = $X + $centerX; $chunkZ = $Z + $centerZ; $index = Level::chunkHash($chunkX, $chunkZ); if (!isset($this->usedChunks[$index])) { if ($this->level->isChunkPopulated($chunkX, $chunkZ)) { $newOrder[$index] = $distance; } else { $generateQueue->insert([$chunkX, $chunkZ], $distance); } } unset($lastChunk[$index]); } } asort($newOrder); if (count($newOrder) > $this->viewDistance) { $count = 0; $this->loadQueue = []; foreach ($newOrder as $k => $distance) { $this->loadQueue[$k] = $distance; if (++$count > $this->viewDistance) { break; } } } else { $this->loadQueue = $newOrder; } $i = 0; while (count($this->loadQueue) < 3 and $generateQueue->count() > 0 and $i < 16) { $d = $generateQueue->extract(); $this->getLevel()->generateChunk($d[0], $d[1]); ++$i; } foreach ($lastChunk as $index => $Yndex) { $X = null; $Z = null; Level::getXZ($index, $X, $Z); foreach ($this->getLevel()->getChunkEntities($X, $Z) as $entity) { if ($entity !== $this) { $entity->despawnFrom($this); } } unset($this->usedChunks[$index]); } }