Пример #1
0
 /**
  * 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();
 }
Пример #2
0
 /**
  * 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();
 }
Пример #3
0
 /**
  * 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();
 }
Пример #4
0
 /**
  * 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();
 }
Пример #5
0
 /**
  * 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();
 }
Пример #6
0
 /**
  * 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();
 }
Пример #7
0
 /**
  * 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();
 }
Пример #8
0
 /**
  *
  * 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]);
     }
 }