chunkHash() public static method

Returns the chunk unique hash/key
public static chunkHash ( integer $x, integer $z ) : string
$x integer
$z integer
return string
 public function onUnloadChunk(ChunkUnloadEvent $event)
 {
     if ($event->getLevel()->getName() !== "world_pvp") {
         return;
     }
     $chunk = $event->getChunk();
     $hash = Level::chunkHash($chunk->getX(), $chunk->getZ());
     if (isset($this->modelLocs[$hash])) {
         foreach ($this->modelLocs[$hash] as $id => $model) {
             if (isset($this->models[$id])) {
                 $this->models[$id]->_kill();
                 unset($this->models[$id]);
             }
         }
     }
     if (isset($this->shopLocs[$hash])) {
         foreach ($this->shopLocs[$hash] as $col => $loc) {
             if (isset($this->shops[$col])) {
                 $this->shops[$col]->_kill();
                 unset($this->shops[$col]);
             }
         }
     }
     if ($hash === $this->bowHash) {
         $this->bow->_kill();
         $this->bow = null;
     }
 }
 public function onUnload(ChunkUnloadEvent $event)
 {
     if ($event->getLevel() === $this->level) {
         foreach ($this->locs[Level::chunkHash($event->getChunk()->getX(), $event->getChunk()->getZ())] as $id => $spawn) {
             if (isset($this->spawns[$spawn->getId()])) {
                 $this->level->removeEntity($this->spawns[$spawn->getId()]);
             }
         }
     }
 }
Exemplo n.º 3
0
 public function resetMine()
 {
     $chunks = [];
     for ($x = $this->getA()->getX(); $x - 16 <= $this->getB()->getX(); $x += 16) {
         for ($z = $this->getA()->getZ(); $z - 16 <= $this->getB()->getZ(); $z += 16) {
             //$this->getLevel()->getServer()->getLogger()->info(Level::chunkHash($x >> 4, $z >> 4));
             $chunk = $this->level->getChunk($x >> 4, $z >> 4, true);
             $chunkClass = get_class($chunk);
             $chunks[Level::chunkHash($x >> 4, $z >> 4)] = $chunk->toBinary();
         }
     }
     //var_dump($chunks);
     $resetTask = new MineResetTask($chunks, $this->a, $this->b, $this->data, $this->getLevel()->getId(), $this->base->getRegionBlocker()->blockZone($this->a, $this->b, $this->level), $chunkClass);
     $this->base->scheduleReset($resetTask);
 }
Exemplo n.º 4
0
 public function spawnTo(Player $player)
 {
     if (!isset($this->hasSpawned[$player->getLoaderId()]) && isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])) {
         $pk = new AddEntityPacket();
         $pk->eid = $this->getID();
         $pk->type = static::NETWORK_ID;
         $pk->x = $this->x;
         $pk->y = $this->y;
         $pk->z = $this->z;
         $pk->speedX = 0;
         $pk->speedY = 0;
         $pk->speedZ = 0;
         $pk->yaw = $this->yaw;
         $pk->pitch = $this->pitch;
         $pk->metadata = $this->dataProperties;
         $player->dataPacket($pk);
         $this->hasSpawned[$player->getLoaderId()] = $player;
     }
 }
 /**
  * Actions to execute when run
  *
  * @return void
  */
 public function onRun()
 {
     $chunkClass = $this->chunkClass;
     /** @var  Chunk[] $chunks */
     $chunks = unserialize($this->chunks);
     foreach ($chunks as $hash => $binary) {
         $chunks[$hash] = $chunkClass::fromBinary($binary);
     }
     $sum = [];
     $id = array_keys(unserialize($this->ratioData));
     for ($i = 0; $i < count($id); $i++) {
         $blockId = explode(":", $id[$i]);
         if (!isset($blockId[1])) {
             $blockId[1] = 0;
         }
         $id[$i] = $blockId;
     }
     $m = array_values(unserialize($this->ratioData));
     $sum[0] = $m[0];
     for ($l = 1; $l < count($m); $l++) {
         $sum[$l] = $sum[$l - 1] + $m[$l];
     }
     for ($x = $this->a->getX(); $x <= $this->b->getX(); $x++) {
         for ($y = $this->a->getY(); $y <= $this->b->getY(); $y++) {
             for ($z = $this->a->getZ(); $z <= $this->b->getZ(); $z++) {
                 $a = rand(0, end($sum));
                 for ($l = 0; $l < count($sum); $l++) {
                     if ($a <= $sum[$l]) {
                         $hash = Level::chunkHash($x >> 4, $z >> 4);
                         if (isset($chunks[$hash])) {
                             $chunks[$hash]->setBlock($x & 0xf, $y & 0x7f, $z & 0xf, $id[$l][0] & 0xff, $id[$l][1] & 0xff);
                         }
                         $l = count($sum);
                     }
                 }
             }
         }
     }
     $this->setResult($chunks);
 }
Exemplo n.º 6
0
 /**
  * Generates a new level if it does not exists
  *
  * @param string $name
  * @param int    $seed
  * @param string $generator Class name that extends pocketmine\level\generator\Generator
  * @param array  $options
  *
  * @return bool
  */
 public function generateLevel($name, $seed = null, $generator = null, $options = [])
 {
     if (trim($name) === "" or $this->isLevelGenerated($name)) {
         return false;
     }
     $seed = $seed === null ? Binary::readInt(@Utils::getRandomBytes(4, false)) : (int) $seed;
     if ($generator !== null and class_exists($generator) and is_subclass_of($generator, Generator::class)) {
         $generator = new $generator($options);
     } else {
         $options["preset"] = $this->getConfigString("generator-settings", "");
         $generator = Generator::getGenerator($this->getLevelType());
     }
     if (($provider = LevelProviderManager::getProviderByName($providerName = $this->getProperty("level-settings.default-format", "mcregion"))) === null) {
         $provider = LevelProviderManager::getProviderByName($providerName = "mcregion");
     }
     try {
         $path = $this->getDataPath() . "worlds/" . $name . "/";
         /** @var \pocketmine\level\format\LevelProvider $provider */
         $provider::generate($path, $name, $seed, $generator, $options);
         $level = new Level($this, $name, $path, $provider);
         $this->levels[$level->getId()] = $level;
         $level->initLevel();
     } catch (\Exception $e) {
         $this->logger->error("Could not generate level \"" . $name . "\": " . $e->getMessage());
         if ($this->logger instanceof MainLogger) {
             $this->logger->logException($e);
         }
         return false;
     }
     $this->getPluginManager()->callEvent(new LevelInitEvent($level));
     $this->getPluginManager()->callEvent(new LevelLoadEvent($level));
     $this->getLogger()->notice("Spawn terrain for level \"{$name}\" is being generated in the background");
     $radiusSquared = ($this->getViewDistance() + 1) / M_PI;
     $radius = ceil(sqrt($radiusSquared));
     $centerX = $level->getSpawnLocation()->getX() >> 4;
     $centerZ = $level->getSpawnLocation()->getZ() >> 4;
     $order = [];
     for ($X = -$radius; $X <= $radius; ++$X) {
         for ($Z = -$radius; $Z <= $radius; ++$Z) {
             $distance = $X ** 2 + $Z ** 2;
             if ($distance > $radiusSquared) {
                 continue;
             }
             $chunkX = $X + $centerX;
             $chunkZ = $Z + $centerZ;
             $index = Level::chunkHash($chunkX, $chunkZ);
             $order[$index] = $distance;
         }
     }
     asort($order);
     $chunkX = $chunkZ = null;
     foreach ($order as $index => $distance) {
         Level::getXZ($index, $chunkX, $chunkZ);
         $level->generateChunk($chunkX, $chunkZ);
     }
     return true;
 }
Exemplo n.º 7
0
 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();
 }
Exemplo n.º 8
0
 protected function loadRegion($x, $z)
 {
     if (!isset($this->regions[$index = Level::chunkHash($x, $z)])) {
         $this->regions[$index] = new RegionLoader($this, $x, $z);
     }
 }
Exemplo n.º 9
0
 protected function enqueueChunk($levelID, $chunkX, $chunkZ)
 {
     if (!isset($this->requestQueue[$levelID])) {
         $this->requestQueue[$levelID] = [];
     }
     if (!isset($this->requestQueue[$levelID][$index = Level::chunkHash($chunkX, $chunkZ)])) {
         $this->requestQueue[$levelID][$index] = 1;
     } else {
         $this->requestQueue[$levelID][$index]++;
         arsort($this->requestQueue[$levelID]);
     }
 }
Exemplo n.º 10
0
 /**
  * Generates a new level if it does not exists
  *
  * @param string $name
  * @param int    $seed
  * @param string $generator Class name that extends pocketmine\level\generator\Noise
  * @param array  $options
  *
  * @return bool
  */
 public function generateLevel($name, $seed = null, $generator = null, $options = [])
 {
     if (trim($name) === "" or $this->isLevelGenerated($name)) {
         return false;
     }
     $seed = $seed === null ? Binary::readInt(@Utils::getRandomBytes(4, false)) : (int) $seed;
     if (!isset($options["preset"])) {
         $options["preset"] = $this->getConfigString("generator-settings", "");
     }
     if (!($generator !== null and class_exists($generator, true) and is_subclass_of($generator, Generator::class))) {
         $generator = Generator::getGenerator($this->getLevelType());
     }
     if (($provider = LevelProviderManager::getProviderByName($providerName = $this->getProperty("level-settings.default-format", "mcregion"))) === null) {
         $provider = LevelProviderManager::getProviderByName($providerName = "mcregion");
     }
     try {
         $path = $this->getDataPath() . "worlds/" . $name . "/";
         /** @var \pocketmine\level\format\LevelProvider $provider */
         $provider::generate($path, $name, $seed, $generator, $options);
         $level = new Level($this, $name, $path, $provider);
         $this->levels[$level->getId()] = $level;
         $level->initLevel();
         $level->setTickRate($this->baseTickRate);
     } catch (\Exception $e) {
         $this->logger->error($this->getLanguage()->translateString("pocketmine.level.generateError", [$name, $e->getMessage()]));
         if ($this->logger instanceof MainLogger) {
             $this->logger->logException($e);
         }
         return false;
     }
     $this->getPluginManager()->callEvent(new LevelInitEvent($level));
     $this->getPluginManager()->callEvent(new LevelLoadEvent($level));
     $this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name]));
     $centerX = $level->getSpawnLocation()->getX() >> 4;
     $centerZ = $level->getSpawnLocation()->getZ() >> 4;
     $order = [];
     for ($X = -3; $X <= 3; ++$X) {
         for ($Z = -3; $Z <= 3; ++$Z) {
             $distance = $X ** 2 + $Z ** 2;
             $chunkX = $X + $centerX;
             $chunkZ = $Z + $centerZ;
             $index = Level::chunkHash($chunkX, $chunkZ);
             $order[$index] = $distance;
         }
     }
     asort($order);
     foreach ($order as $index => $distance) {
         Level::getXZ($index, $chunkX, $chunkZ);
         $level->populateChunk($chunkX, $chunkZ, true);
     }
     return true;
 }
Exemplo n.º 11
0
 public function setChunk($chunkX, $chunkZ, FullChunk $chunk)
 {
     if (!$chunk instanceof Chunk) {
         throw new ChunkException("Invalid Chunk class");
     }
     $chunk->setProvider($this);
     $chunk->setX($chunkX);
     $chunk->setZ($chunkZ);
     if (isset($this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)]) and $this->chunks[$index] !== $chunk) {
         $this->unloadChunk($chunkX, $chunkZ, false);
     }
     $this->chunks[$index] = $chunk;
 }
Exemplo n.º 12
0
 /**
  * Changes the biome of a plot
  *
  * @api
  * @param Plot $plot
  * @param Biome $biome
  * @return bool
  */
 public function setPlotBiome(Plot $plot, Biome $biome)
 {
     $plotLevel = $this->getLevelSettings($plot->levelName);
     if ($plotLevel === null) {
         return false;
     }
     $level = $this->getServer()->getLevelByName($plot->levelName);
     $pos = $this->getPlotPosition($plot);
     $plotSize = $plotLevel->plotSize;
     $xMax = $pos->x + $plotSize;
     $zMax = $pos->z + $plotSize;
     $chunkIndexes = [];
     for ($x = $pos->x; $x < $xMax; $x++) {
         for ($z = $pos->z; $z < $zMax; $z++) {
             $index = Level::chunkHash($x >> 4, $z >> 4);
             if (!in_array($index, $chunkIndexes)) {
                 $chunkIndexes[] = $index;
             }
             $color = $biome->getColor();
             $R = $color >> 16;
             $G = $color >> 8 & 0xff;
             $B = $color & 0xff;
             $level->setBiomeColor($x, $z, $R, $G, $B);
         }
     }
     foreach ($chunkIndexes as $index) {
         Level::getXZ($index, $X, $Z);
         $chunk = $level->getChunk($X, $Z);
         foreach ($level->getChunkPlayers($X, $Z) as $player) {
             $player->onChunkChanged($chunk);
         }
     }
     $plot->biome = $biome->getName();
     $this->dataProvider->savePlot($plot);
     return true;
 }
Exemplo n.º 13
0
 /**
  * @param Player $player
  */
 public function spawnTo(Player $player)
 {
     if (!isset($this->hasSpawned[$player->getLoaderId()]) and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])) {
         $this->hasSpawned[$player->getLoaderId()] = $player;
     }
 }
Exemplo n.º 14
0
 protected function generateChunk($levelID, $chunkX, $chunkZ)
 {
     if (isset($this->levels[$levelID]) and !isset($this->generatedQueue[$levelID][$index = Level::chunkHash($chunkX, $chunkZ)])) {
         $this->levels[$levelID]->populateChunk($chunkX, $chunkZ);
         //Request population directly
         if (isset($this->levels[$levelID])) {
             $this->generatedQueue[$levelID][$index] = true;
             foreach ($this->levels[$levelID]->getChangedChunks() as $index => $chunk) {
                 if ($chunk->isPopulated()) {
                     $this->sendChunk($levelID, $chunk);
                     $this->levels[$levelID]->cleanChangedChunk($index);
                 }
             }
             if (count($this->generatedQueue[$levelID]) > 4) {
                 $this->levels[$levelID]->doGarbageCollection();
                 $this->generatedQueue[$levelID] = [];
                 $this->levels[$levelID]->cleanChangedChunks();
             }
         }
     }
 }
 /**
  * @param int       $chunkX
  * @param int       $chunkZ
  * @param FullChunk $chunk
  */
 public function setChunk($chunkX, $chunkZ, FullChunk $chunk)
 {
     $this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)] = $chunk;
     $this->changes[$index] = $chunk;
     if ($chunk->isPopulated()) {
         //TODO: Queue to be sent
     }
 }
Exemplo n.º 16
0
 protected function checkTeleportPosition()
 {
     if ($this->teleportPosition !== null) {
         $chunkX = $this->teleportPosition->x >> 4;
         $chunkZ = $this->teleportPosition->z >> 4;
         for ($X = -1; $X <= 1; ++$X) {
             for ($Z = -1; $Z <= 1; ++$Z) {
                 if (!isset($this->usedChunks[$index = Level::chunkHash($chunkX + $X, $chunkZ + $Z)]) or $this->usedChunks[$index] === false) {
                     return false;
                 }
             }
         }
         $this->sendPosition($this, null, null, 1, Network::CHANNEL_WORLD_CHUNKS);
         $this->forceMovement = $this->teleportPosition;
         $this->teleportPosition = null;
         return true;
     }
     return true;
 }
Exemplo n.º 17
0
 public function loadChunk($chunkX, $chunkZ, $create = false)
 {
     $index = Level::chunkHash($chunkX, $chunkZ);
     if (isset($this->chunks[$index])) {
         return true;
     }
     $regionX = $regionZ = null;
     self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
     $this->loadRegion($regionX, $regionZ);
     $this->level->timings->syncChunkLoadDataTimer->startTiming();
     $chunk = $this->getRegion($regionX, $regionZ)->readChunk($chunkX - $regionX * 32, $chunkZ - $regionZ * 32);
     if ($chunk === null and $create) {
         $chunk = $this->getEmptyChunk($chunkX, $chunkZ);
     }
     $this->level->timings->syncChunkLoadDataTimer->stopTiming();
     if ($chunk !== null) {
         $this->chunks[$index] = $chunk;
         return true;
     } else {
         return false;
     }
 }
Exemplo n.º 18
0
 public function spawnTo(Player $player)
 {
     if (isset($this->hasSpawned[$player->getLoaderId()]) or !isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])) {
         return;
     }
     if (!$this->dummyReceiver instanceof DummyReceiver) {
         return;
     }
     $pk = new AddPlayerPacket();
     $pk->uuid = $this->dummyReceiver->randomUUID;
     $pk->username = $this->dummyReceiver->getName();
     $pk->eid = $this->getId();
     $pk->x = $this->x;
     $pk->y = $this->y;
     $pk->z = $this->z;
     $pk->speedX = $this->motionX;
     $pk->speedY = $this->motionY;
     $pk->speedZ = $this->motionZ;
     $pk->yaw = $this->yaw;
     $pk->pitch = $this->pitch;
     $pk->item = Item::get(Item::DIAMOND_PICKAXE);
     $pk->metadata = $this->dummyReceiver->getDataProperties();
     $player->dataPacket($pk);
     $this->dummyReceiver->getInventory()->sendArmorContents($player);
     if (!$this instanceof Player) {
         $this->server->removePlayerListData($this->dummyReceiver->randomUUID, [$player]);
     }
     $this->hasSpawned[$player->getLoaderId()] = $player;
 }
Exemplo n.º 19
0
 public function generateChunk($chunkX, $chunkZ)
 {
     $this->random->setSeed(0xdeadbeef ^ $chunkX << 8 ^ $chunkZ ^ $this->level->getSeed());
     $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
     $chunk = $this->level->getChunk($chunkX, $chunkZ);
     $biomeCache = [];
     for ($x = 0; $x < 16; ++$x) {
         for ($z = 0; $z < 16; ++$z) {
             $minSum = 0;
             $maxSum = 0;
             $weightSum = 0;
             $biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z);
             $chunk->setBiomeId($x, $z, $biome->getId());
             $color = [0, 0, 0];
             for ($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx) {
                 for ($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz) {
                     $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE];
                     if ($sx === 0 and $sz === 0) {
                         $adjacent = $biome;
                     } else {
                         $index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
                         if (isset($biomeCache[$index])) {
                             $adjacent = $biomeCache[$index];
                         } else {
                             $biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
                         }
                     }
                     $minSum += ($adjacent->getMinElevation() - 1) * $weight;
                     $maxSum += $adjacent->getMaxElevation() * $weight;
                     $bColor = $adjacent->getColor();
                     $color[0] += ($bColor >> 16) ** 2 * $weight;
                     $color[1] += ($bColor >> 8 & 0xff) ** 2 * $weight;
                     $color[2] += ($bColor & 0xff) ** 2 * $weight;
                     $weightSum += $weight;
                 }
             }
             $minSum /= $weightSum;
             $maxSum /= $weightSum;
             $chunk->setBiomeColor($x, $z, sqrt($color[0] / $weightSum), sqrt($color[1] / $weightSum), sqrt($color[2] / $weightSum));
             $solidLand = false;
             for ($y = 127; $y >= 0; --$y) {
                 if ($y === 0) {
                     $chunk->setBlockId($x, $y, $z, Block::BEDROCK);
                     continue;
                 }
                 // A noiseAdjustment of 1 will guarantee ground, a noiseAdjustment of -1 will guarantee air.
                 //$effHeight = min($y - $smoothHeight - $minSum,
                 $noiseAdjustment = 2 * (($maxSum - $y) / ($maxSum - $minSum)) - 1;
                 // To generate caves, we bring the noiseAdjustment down away from 1.
                 $caveLevel = $minSum - 10;
                 $distAboveCaveLevel = max(0, $y - $caveLevel);
                 // must be positive
                 $noiseAdjustment = min($noiseAdjustment, 0.4 + $distAboveCaveLevel / 10);
                 $noiseValue = $noise[$x][$z][$y] + $noiseAdjustment;
                 if ($noiseValue > 0) {
                     $chunk->setBlockId($x, $y, $z, Block::STONE);
                     $solidLand = true;
                 } elseif ($y <= $this->waterHeight && $solidLand == false) {
                     $chunk->setBlockId($x, $y, $z, Block::STILL_WATER);
                 }
             }
         }
     }
     foreach ($this->generationPopulators as $populator) {
         $populator->populate($this->level, $chunkX, $chunkZ, $this->random);
     }
 }
Exemplo n.º 20
0
 public function setChunk($chunkX, $chunkZ, FullChunk $chunk)
 {
     if (!$chunk instanceof Chunk) {
         throw new \Exception("Invalid Chunk class");
     }
     $chunk->setProvider($this);
     if ($chunk->isPopulated() === false) {
         $this->unloadChunk($chunkX, $chunkZ, false);
         $regionX = $regionZ = null;
         self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
         $this->loadRegion($regionX, $regionZ);
         $region = $this->getRegion($regionX, $regionZ);
         $region->removeChunk($chunkX - $region->getX() * 32, $chunkZ - $region->getZ() * 32);
         $this->loadChunk($chunkX, $chunkZ);
     } else {
         $chunk->setX($chunkX);
         $chunk->setZ($chunkZ);
         $this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk;
         //$this->saveChunk($chunkX, $chunkZ);
     }
 }
Exemplo n.º 21
0
 protected function orderChunks()
 {
     if ($this->connected === false) {
         return false;
     }
     $this->nextChunkOrderRun = 200;
     $radiusSquared = $this->viewDistance;
     $radius = ceil(sqrt($radiusSquared));
     $side = ceil($radius / 2);
     $newOrder = [];
     $lastChunk = $this->usedChunks;
     $currentQueue = [];
     $centerX = $this->x >> 4;
     $centerZ = $this->z >> 4;
     for ($X = -$side; $X <= $side; ++$X) {
         for ($Z = -$side; $Z <= $side; ++$Z) {
             $chunkX = $X + $centerX;
             $chunkZ = $Z + $centerZ;
             if (!isset($this->usedChunks[$index = Level::chunkHash($chunkX, $chunkZ)])) {
                 $newOrder[$index] = abs($X) + abs($Z);
             } else {
                 $currentQueue[$index] = abs($X) + abs($Z);
             }
         }
     }
     asort($newOrder);
     asort($currentQueue);
     $limit = $this->viewDistance;
     foreach ($currentQueue as $index => $distance) {
         if ($limit-- <= 0) {
             break;
         }
         unset($lastChunk[$index]);
     }
     foreach ($lastChunk as $index => $Yndex) {
         $X = null;
         $Z = null;
         Level::getXZ($index, $X, $Z);
         $this->unloadChunk($X, $Z);
     }
     $loadedChunks = count($this->usedChunks);
     if (count($newOrder) + $loadedChunks > $this->viewDistance) {
         $count = $loadedChunks;
         $this->loadQueue = [];
         foreach ($newOrder as $k => $distance) {
             if (++$count > $this->viewDistance) {
                 break;
             }
             $this->loadQueue[$k] = $distance;
         }
     } else {
         $this->loadQueue = $newOrder;
     }
     return true;
 }
Exemplo n.º 22
0
 protected function loadRegion($x, $z)
 {
     if (isset($this->regions[$index = Level::chunkHash($x, $z)])) {
         return true;
     }
     $this->regions[$index] = new RegionLoader($this, $x, $z);
     return true;
 }
Exemplo n.º 23
0
 /**
  * @param int $chunkX
  * @param int $chunkZ
  * @param FullChunk $chunk
  */
 public function setChunk($chunkX, $chunkZ, FullChunk $chunk = null)
 {
     if ($chunk === null) {
         unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]);
         return;
     }
     $this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk;
 }
Exemplo n.º 24
0
 protected function checkTeleportPosition()
 {
     if ($this->teleportPosition !== null) {
         $chunkX = $this->teleportPosition->x >> 4;
         $chunkZ = $this->teleportPosition->z >> 4;
         for ($X = -1; $X <= 1; ++$X) {
             for ($Z = -1; $Z <= 1; ++$Z) {
                 if (!isset($this->usedChunks[$index = Level::chunkHash($chunkX + $X, $chunkZ + $Z)]) or $this->usedChunks[$index] === false) {
                     return false;
                 }
             }
         }
         $this->sendPosition($this, $this->pitch, $this->yaw, 1);
         $this->spawnToAll();
         $this->forceMovement = $this->teleportPosition;
         $this->teleportPosition = null;
         return true;
     }
     return true;
 }
Exemplo n.º 25
0
 protected function queueUnloadChunk($x, $z)
 {
     $this->unloadQueue[Level::chunkHash($x, $z)] = microtime(true);
 }
Exemplo n.º 26
0
 public function addPlayerMovement($chunkX, $chunkZ, $entityId, $x, $y, $z, $yaw, $pitch, $onGround, $headYaw = null)
 {
     if (!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])) {
         $this->moveToSend[$index] = [];
     }
     $pk = new MovePlayerPacket();
     $pk->eid = $entityId;
     $pk->x = $x;
     $pk->y = $y;
     $pk->z = $z;
     $pk->yaw = $headYaw === null ? $yaw : $headYaw;
     $pk->bodyYaw = $yaw;
     $pk->pitch = $pitch;
     $pk->onGround = $onGround;
     $pk->mode = MovePlayerPacket::MODE_NORMAL;
     $this->moveToSend[$index][$entityId] = $pk;
 }
Exemplo n.º 27
0
 public function onChunkChanged(FullChunk $chunk)
 {
     $this->loadQueue[Level::chunkHash($chunk->getX(), $chunk->getZ())] = abs(($this->x >> 4) - $chunk->getX()) + abs(($this->z >> 4) - $chunk->getZ());
 }
Exemplo n.º 28
0
 public function generateChunk($chunkX, $chunkZ)
 {
     $this->random->setSeed(0xdeadbeef ^ $chunkX << 8 ^ $chunkZ ^ $this->level->getSeed());
     $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16);
     $chunk = $this->level->getChunk($chunkX, $chunkZ);
     $biomeCache = [];
     for ($x = 0; $x < 16; ++$x) {
         for ($z = 0; $z < 16; ++$z) {
             $minSum = 0;
             $maxSum = 0;
             $weightSum = 0;
             $biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z);
             $chunk->setBiomeId($x, $z, $biome->getId());
             $color = [0, 0, 0];
             for ($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx) {
                 for ($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz) {
                     $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE];
                     if ($sx === 0 and $sz === 0) {
                         $adjacent = $biome;
                     } else {
                         $index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
                         if (isset($biomeCache[$index])) {
                             $adjacent = $biomeCache[$index];
                         } else {
                             $biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz);
                         }
                     }
                     $minSum += ($adjacent->getMinElevation() - 1) * $weight;
                     $maxSum += $adjacent->getMaxElevation() * $weight;
                     $bColor = $adjacent->getColor();
                     $color[0] += ($bColor >> 16) ** 2 * $weight;
                     $color[1] += ($bColor >> 8 & 0xff) ** 2 * $weight;
                     $color[2] += ($bColor & 0xff) ** 2 * $weight;
                     $weightSum += $weight;
                 }
             }
             $minSum /= $weightSum;
             $maxSum /= $weightSum;
             $chunk->setBiomeColor($x, $z, sqrt($color[0] / $weightSum), sqrt($color[1] / $weightSum), sqrt($color[2] / $weightSum));
             $smoothHeight = ($maxSum - $minSum) / 2;
             for ($y = 0; $y < 128; ++$y) {
                 if ($y === 0) {
                     $chunk->setBlockId($x, $y, $z, Block::BEDROCK);
                     continue;
                 }
                 $noiseValue = $noise[$x][$z][$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum);
                 if ($noiseValue > 0) {
                     $chunk->setBlockId($x, $y, $z, Block::STONE);
                 } elseif ($y <= $this->waterHeight) {
                     $chunk->setBlockId($x, $y, $z, Block::STILL_WATER);
                 }
             }
         }
     }
     foreach ($this->generationPopulators as $populator) {
         $populator->populate($this->level, $chunkX, $chunkZ, $this->random);
     }
 }
Exemplo n.º 29
0
 public function addEntityMovement($chunkX, $chunkZ, $entityId, $x, $y, $z, $yaw, $pitch, $headYaw = null)
 {
     if (!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])) {
         $this->moveToSend[$index] = [];
     }
     $this->moveToSend[$index][$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch];
 }
Exemplo n.º 30
0
 public function serverToInterface(DesktopPlayer $player, DataPacket $packet)
 {
     switch ($packet->pid()) {
         case Info::DISCONNECT_PACKET:
             if ($player->bigBrother_getStatus() === 0) {
                 $pk = new LoginDisconnectPacket();
                 $pk->reason = TextFormat::toJSON($packet->message === "" ? "You have been disconnected." : $packet->message);
             } else {
                 $pk = new PlayDisconnectPacket();
                 $pk->reason = TextFormat::toJSON($packet->message === "" ? "You have been disconnected." : $packet->message);
             }
             return $pk;
         case Info::TEXT_PACKET:
             echo $player->getSetting("Lang") . "\n";
             /*if($packet->message === "chat.type.achievement"){
             		/*$pk = new ScoreboardObjectivePacket();
             		$pk->ObjectiveName = $packet->parameters[0];
             		$pk->Mode = 0;
             		$pk->ObjectiveValue = 3;
             		return $pk;*/
             /*echo "TextPacket: achievement\n";
             			return null;
             		}else{
             			$pk = new STCChatPacket();
             			$pk->message = TextFormat::toJSON($packet->message, $packet->type, $packet->parameters);
             		}*/
             //return $pk;
             return null;
         case Info::SET_TIME_PACKET:
             $pk = new TimeUpdatePacket();
             $pk->age = $packet->time;
             $pk->time = $packet->time;
             //TODO: calculate offset from MCPE
             return $pk;
         case Info::START_GAME_PACKET:
             $packets = [];
             $pk = new JoinGamePacket();
             $pk->eid = $packet->eid;
             $pk->gamemode = $packet->gamemode;
             $pk->dimension = 0;
             $pk->difficulty = $player->getServer()->getDifficulty();
             $pk->maxPlayers = $player->getServer()->getMaxPlayers();
             $pk->levelType = "default";
             $packets[] = $pk;
             $pk = new SpawnPositionPacket();
             $pk->spawnX = $packet->spawnX;
             $pk->spawnY = $packet->spawnY;
             $pk->spawnZ = $packet->spawnZ;
             $packets[] = $pk;
             $pk = new PlayerAbilitiesPacket();
             $pk->flyingSpeed = 0.05;
             $pk->walkingSpeed = 0.1;
             $pk->canFly = ($player->getGamemode() & 0x1) > 0;
             $pk->damageDisabled = ($player->getGamemode() & 0x1) > 0;
             $pk->isFlying = false;
             $pk->isCreative = ($player->getGamemode() & 0x1) > 0;
             $packets[] = $pk;
             $pk = new PositionAndLookPacket();
             $pk->x = $packet->x;
             $pk->y = $packet->y;
             $pk->z = $packet->z;
             $pk->yaw = $player->yaw;
             $pk->pitch = $player->pitch;
             $packets[] = $pk;
             return $packets;
         case Info::ADD_PLAYER_PACKET:
             $packets = [];
             $packetplayer = $player->getServer()->getPlayerExact($packet->username);
             $pk = new PlayerListPacket();
             $pk->actionID = PlayerListPacket::TYPE_ADD;
             $pk->players[] = [$packetplayer->getUniqueId()->toBinary(), $packetplayer->getName(), [], $packetplayer->getGamemode(), 0, false];
             if ($packetplayer instanceof DesktopPlayer) {
                 $pk->players[0][2] = $packetplayer->bigBrother_getPeroperties();
             }
             $packets[] = $pk;
             $pk = new SpawnPlayerPacket();
             $pk->eid = $packet->eid;
             $pk->uuid = $packetplayer->getUniqueId()->toBinary();
             $pk->x = $packet->x;
             $pk->z = $packet->z;
             $pk->y = $packet->y;
             $pk->yaw = $packet->yaw;
             $pk->pitch = $packet->pitch;
             $pk->item = $packetplayer->getInventory()->getItemInHand()->getId();
             $pk->metadata = $packet->metadata;
             $packets[] = $pk;
             $pk = new EntityTeleportPacket();
             $pk->eid = $packet->eid;
             $pk->x = $packet->x;
             $pk->y = $packet->y;
             $pk->z = $packet->z;
             $pk->yaw = $packet->yaw;
             $pk->pitch = $packet->pitch;
             $packets[] = $pk;
             return $packets;
             /*case Info::ADD_ENTITY_PACKET:
             		return null;*/
             /*case Info::REMOVE_PLAYER_PACKET:
             				$pk = new PlayerListPacket();
             				$pk->actionID = PlayerListPacket::TYPE_REMOVE;
             
             				$pk->players[] = [
             					$packet->clientId->toBinary()
             				];
             				$packets[] = $pk;
             
             				$pk = new DestroyEntitiesPacket();
             				$pk->ids[] = $packet->eid;
             				$packets[] = $pk;
             
             				return $packets;*/
         /*case Info::ADD_ENTITY_PACKET:
         		return null;*/
         /*case Info::REMOVE_PLAYER_PACKET:
         				$pk = new PlayerListPacket();
         				$pk->actionID = PlayerListPacket::TYPE_REMOVE;
         
         				$pk->players[] = [
         					$packet->clientId->toBinary()
         				];
         				$packets[] = $pk;
         
         				$pk = new DestroyEntitiesPacket();
         				$pk->ids[] = $packet->eid;
         				$packets[] = $pk;
         
         				return $packets;*/
         case Info::REMOVE_ENTITY_PACKET:
             $pk = new DestroyEntitiesPacket();
             $pk->ids[] = $packet->eid;
             return $pk;
         case Info::ADD_ITEM_ENTITY_PACKET:
             $packets = [];
             $pk = new SpawnObjectPacket();
             $pk->eid = $packet->eid;
             $pk->type = 2;
             $pk->x = $packet->x;
             $pk->y = $packet->y;
             $pk->z = $packet->z;
             $pk->yaw = $player->yaw;
             $pk->pitch = $player->pitch;
             $packets[] = $pk;
             $pk = new EntityMetadataPacket();
             $pk->eid = $packet->eid;
             $pk->metadata = [0 => [0 => 0, 1 => 0], 10 => [0 => 5, 1 => $packet->item]];
             $packets[] = $pk;
             return $packets;
             /*case Info::REMOVE_ITEM_ENTITY_PACKET:
             		return null;*/
         /*case Info::REMOVE_ITEM_ENTITY_PACKET:
         		return null;*/
         case Info::MOVE_ENTITY_PACKET:
             $packets = [];
             foreach ($packet->entities as $d) {
                 $pk = new EntityTeleportPacket();
                 $pk->eid = $d[0];
                 $pk->x = $d[1];
                 $pk->y = $d[2] - $player->getEyeHeight();
                 $pk->z = $d[3];
                 $pk->yaw = $d[4];
                 $pk->pitch = $d[6];
                 $packets[] = $pk;
                 $pk = new EntityHeadLookPacket();
                 $pk->eid = $d[0];
                 $pk->yaw = $d[5];
                 $packets[] = $pk;
             }
             return $packets;
         case Info::MOVE_PLAYER_PACKET:
             if ($packet->eid === 0) {
                 $pk = new PositionAndLookPacket();
                 $pk->x = $packet->x;
                 $pk->y = $packet->y - $player->getEyeHeight();
                 $pk->z = $packet->z;
                 $pk->yaw = $packet->yaw;
                 $pk->pitch = $packet->pitch;
                 $pk->onGround = $player->isOnGround();
                 return $pk;
             } else {
                 $packets = [];
                 $pk = new EntityTeleportPacket();
                 $pk->eid = $packet->eid;
                 $pk->x = $packet->x;
                 $pk->y = $packet->y - $player->getEyeHeight();
                 $pk->z = $packet->z;
                 $pk->yaw = $packet->yaw;
                 $pk->pitch = $packet->pitch;
                 $packets[] = $pk;
                 $pk = new EntityHeadLookPacket();
                 $pk->eid = $packet->eid;
                 $pk->yaw = $packet->yaw;
                 $packets[] = $pk;
                 return $packets;
             }
         case Info::UPDATE_BLOCK_PACKET:
             //TODO
             $pk = new BlockChangePacket();
             $pk->x = $packet->x;
             $pk->y = $packet->y;
             $pk->z = $packet->z;
             $pk->blockId = $packet->blockId;
             $pk->blockMeta = $packet->blockData;
             return $pk;
         case Info::MOB_EQUIPMENT_PACKET:
             $pk = new EntityEquipmentPacket();
             $pk->eid = $packet->eid;
             $pk->slot = $packet->slot;
             $pk->item = $packet->item;
             return $pk;
         case Info::MOB_ARMOR_EQUIPMENT_PACKET:
             $packets = [];
             foreach ($packet->slots as $num => $item) {
                 $pk = new EntityEquipmentPacket();
                 $pk->eid = $packet->eid;
                 $pk->slot = $num + 1;
                 $pk->item = $item;
                 $packets[] = $pk;
             }
             return $packets;
         case Info::SET_ENTITY_DATA_PACKET:
             /*if(isset($packet->metadata[16])){
             			if($packet->metadata[16][1] === 2){
             				$pk = new UseBedPacket(); //Bug
             				$pk->eid = $packet->eid;
             				$bedXYZ = $player->getSetting("BedXYZ");
             				$pk->bedX = $bedXYZ[0];
             				$pk->bedY = $bedXYZ[1];
             				$pk->bedZ = $bedXYZ[2];
             				$player->removeSetting("BedXYZ");
             			}else{
             				$pk = new CAnimatePacket();
             				$pk->eid = $packet->eid;
             				$pk->actionID = 2;
             			}
             			return $pk;
             		}elseif(isset($packet->metadata[17])){
             			$player->setSetting(["BedXYZ" => $packet->metadata[17][1]]);
             		}*/
             $pk = new EntityMetadataPacket();
             $pk->eid = $packet->eid;
             $pk->metadata = $packet->metadata;
             return $pk;
         case Info::SET_ENTITY_MOTION_PACKET:
             $pk = new EntityVelocityPacket();
             $pk->eid = $packet->eid;
             $pk->velocityX = $packet->motionX;
             $pk->velocityY = $packet->motionY;
             $pk->velocityZ = $packet->motionZ;
             return $pk;
         case Info::SET_HEALTH_PACKET:
             $pk = new UpdateHealthPacket();
             $pk->health = $packet->health;
             $pk->food = 20;
             $pk->saturation = 5;
             return $pk;
         case Info::SET_SPAWN_POSITION_PACKET:
             $pk = new SpawnPositionPacket();
             $pk->spawnX = $packet->x;
             $pk->spawnY = $packet->y;
             $pk->spawnZ = $packet->z;
             return $pk;
         case Info::ANIMATE_PACKET:
             switch ($packet->action) {
                 case 1:
                     $pk = new CAnimatePacket();
                     $pk->actionID = 0;
                     $pk->eid = $packet->eid;
                     return $pk;
                     break;
                 case 3:
                     //LeaveBed
                     $pk = new CAnimatePacket();
                     $pk->actionID = 2;
                     $pk->eid = $packet->eid;
                     return $pk;
                     break;
                 default:
                     echo "AnimatePacket: " . $packet->action . "\n";
                     break;
             }
             return null;
         case Info::RESPAWN_PACKET:
             $pk = new CRespawnPacket();
             $pk->dimension = 0;
             $pk->difficulty = $player->getServer()->getDifficulty();
             $pk->gamemode = $player->getGamemode();
             $pk->levelType = "default";
             return $pk;
             /*case Info::CONTAINER_OPEN_PACKET:
             				$pk = new OpenWindowPacket();
             				$pk->windowID = $packet->windowid;
             				$pk->inventoryType = $packet->type;
             				$pk->windowTitle = "";
             				$pk->slots = $packet->slots;
             				return $pk;
             
             			case Info::CONTAINER_CLOSE_PACKET:
             				$pk = new STCCloseWindowPacket();
             				$pk->windowID = $packet->windowid;
             				return $pk;
             
             			case Info::CONTAINER_SET_SLOT_PACKET:
             				echo "ContainerSetSlotPacket: 0x".bin2hex(chr($packet->windowid))."\n";
             				$pk = new SetSlotPacket();
             				$pk->windowID = $packet->windowid;
             				if($pk->windowID === 0x00){
             					$pk->slot = $packet->slot + 36;
             				}elseif($pk->windowID === 0x78){
             					$pk->windowID = 0;
             					$pk->slot = $packet->slot + 5;
             				}else{
             					$pk->slot = $packet->slot;
             				}
             				$pk->item = $packet->item;
             				return $pk;
             
             			case Info::CONTAINER_SET_CONTENT_PACKET://Bug
             				echo "ContainerSetContentPacket: 0x".bin2hex(chr($packet->windowid))."\n";
             				if($packet->windowid !== 0x79 and $packet->windowid !== 0x78){
             					$pk = new WindowItemsPacket();
             					$pk->windowID = 0;
             					for($i = 0; $i < 5; ++$i){
             						$pk->items[] = Item::get(Item::AIR, 0, 0);
             					}
             					$pk->items[] = $player->getInventory()->getHelmet();
             					$pk->items[] = $player->getInventory()->getChestplate();
             					$pk->items[] = $player->getInventory()->getLeggings();
             					$pk->items[] = $player->getInventory()->getBoots();
             
             					if($player->getGamemode() === 0){
             						for($i = 9; $i < 36; ++$i){
             							$pk->items[] = $player->getInventory()->getItem($i);
             						}
             					}else{
             						for($i = 0; $i < 27; ++$i){
             							$pk->items[] = Item::get(Item::AIR, 0, 0);
             						}
             					}
             					for($i = 0; $i < 9; ++$i){
             						$pk->items[] = $player->getInventory()->getItem($i);
             					}
             					return $pk;
             				}
             				return null;*/
         /*case Info::CONTAINER_OPEN_PACKET:
         				$pk = new OpenWindowPacket();
         				$pk->windowID = $packet->windowid;
         				$pk->inventoryType = $packet->type;
         				$pk->windowTitle = "";
         				$pk->slots = $packet->slots;
         				return $pk;
         
         			case Info::CONTAINER_CLOSE_PACKET:
         				$pk = new STCCloseWindowPacket();
         				$pk->windowID = $packet->windowid;
         				return $pk;
         
         			case Info::CONTAINER_SET_SLOT_PACKET:
         				echo "ContainerSetSlotPacket: 0x".bin2hex(chr($packet->windowid))."\n";
         				$pk = new SetSlotPacket();
         				$pk->windowID = $packet->windowid;
         				if($pk->windowID === 0x00){
         					$pk->slot = $packet->slot + 36;
         				}elseif($pk->windowID === 0x78){
         					$pk->windowID = 0;
         					$pk->slot = $packet->slot + 5;
         				}else{
         					$pk->slot = $packet->slot;
         				}
         				$pk->item = $packet->item;
         				return $pk;
         
         			case Info::CONTAINER_SET_CONTENT_PACKET://Bug
         				echo "ContainerSetContentPacket: 0x".bin2hex(chr($packet->windowid))."\n";
         				if($packet->windowid !== 0x79 and $packet->windowid !== 0x78){
         					$pk = new WindowItemsPacket();
         					$pk->windowID = 0;
         					for($i = 0; $i < 5; ++$i){
         						$pk->items[] = Item::get(Item::AIR, 0, 0);
         					}
         					$pk->items[] = $player->getInventory()->getHelmet();
         					$pk->items[] = $player->getInventory()->getChestplate();
         					$pk->items[] = $player->getInventory()->getLeggings();
         					$pk->items[] = $player->getInventory()->getBoots();
         
         					if($player->getGamemode() === 0){
         						for($i = 9; $i < 36; ++$i){
         							$pk->items[] = $player->getInventory()->getItem($i);
         						}
         					}else{
         						for($i = 0; $i < 27; ++$i){
         							$pk->items[] = Item::get(Item::AIR, 0, 0);
         						}
         					}
         					for($i = 0; $i < 9; ++$i){
         						$pk->items[] = $player->getInventory()->getItem($i);
         					}
         					return $pk;
         				}
         				return null;*/
         case Info::CRAFTING_DATA_PACKET:
             $player->setSetting(["Recipes" => $packet->entries, "cleanRecipes" => $packet->cleanRecipes]);
             return null;
         case Info::BLOCK_ENTITY_DATA_PACKET:
             $nbt = new NBT(NBT::LITTLE_ENDIAN);
             $nbt->read($packet->namedtag);
             $nbt = $nbt->getData();
             if ($nbt["id"] !== Tile::SIGN) {
                 return null;
             } else {
                 $index = Level::chunkHash($packet->x >> 4, $packet->z >> 4);
                 if (isset($player->usedChunks[$index]) and $player->usedChunks[$index]) {
                     $pk = new UpdateSignPacket();
                     $pk->x = $packet->x;
                     $pk->y = $packet->y;
                     $pk->z = $packet->z;
                     $pk->line1 = TextFormat::toJSON($nbt["Text1"]);
                     $pk->line2 = TextFormat::toJSON($nbt["Text2"]);
                     $pk->line3 = TextFormat::toJSON($nbt["Text3"]);
                     $pk->line4 = TextFormat::toJSON($nbt["Text4"]);
                     return $pk;
                 }
             }
             return null;
         case Info::SET_DIFFICULTY_PACKET:
             $pk = new ServerDifficultyPacket();
             $pk->difficulty = $packet->difficulty;
             return $pk;
         case Info::SET_PLAYER_GAMETYPE_PACKET:
             $packets = [];
             $pk = new PlayerAbilitiesPacket();
             $pk->flyingSpeed = 0.05;
             $pk->walkingSpeed = 0.1;
             $pk->canFly = ($player->getGamemode() & 0x1) > 0;
             $pk->damageDisabled = ($player->getGamemode() & 0x1) > 0;
             $pk->isFlying = false;
             $pk->isCreative = ($player->getGamemode() & 0x1) > 0;
             $packets[] = $pk;
             $pk = new ChangeGameStatePacket();
             $pk->reason = 3;
             $pk->value = $player->getGamemode();
             $packets[] = $pk;
             return $packets;
         case Info::PLAY_STATUS_PACKET:
         case Info::PLAYER_LIST_PACKET:
         case Info::ADVENTURE_SETTINGS_PACKET:
         case Info::FULL_CHUNK_DATA_PACKET:
         case Info::BATCH_PACKET:
             return null;
         default:
             echo "[Send] 0x" . bin2hex(chr($packet->pid())) . "\n";
             return null;
     }
 }