readInt() public static method

public static readInt ( $str )
示例#1
0
 /**
  * @param LevelProvider $provider
  * @param int           $x
  * @param int           $z
  * @param string        $blocks
  * @param string        $data
  * @param string        $skyLight
  * @param string        $blockLight
  * @param string        $biomeIds
  * @param int[]         $biomeColors
  * @param int[]         $heightMap
  * @param Compound[]    $entities
  * @param Compound[]    $tiles
  */
 protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, $biomeIds = null, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = [])
 {
     $this->provider = $provider;
     $this->x = (int) $x;
     $this->z = (int) $z;
     $this->blocks = $blocks;
     $this->data = $data;
     $this->skyLight = $skyLight;
     $this->blockLight = $blockLight;
     if (strlen($biomeIds) === 256) {
         $this->biomeIds = $biomeIds;
     } else {
         $this->biomeIds = str_repeat("", 256);
     }
     if (count($biomeColors) === 256) {
         $this->biomeColors = $biomeColors;
     } else {
         $this->biomeColors = array_fill(0, 256, Binary::readInt("…²J"));
     }
     if (count($heightMap) === 256) {
         $this->heightMap = $heightMap;
     } else {
         $this->heightMap = array_fill(0, 256, 127);
     }
     $this->NBTtiles = $tiles;
     $this->NBTentities = $entities;
 }
示例#2
0
 public function generateChunk($x, $z)
 {
     $nbt = new Compound("Level", []);
     $nbt->xPos = new Int("xPos", $this->getX() * 32 + $x);
     $nbt->zPos = new Int("zPos", $this->getZ() * 32 + $z);
     $nbt->LastUpdate = new Long("LastUpdate", 0);
     $nbt->LightPopulated = new Byte("LightPopulated", 0);
     $nbt->TerrainPopulated = new Byte("TerrainPopulated", 0);
     $nbt->V = new Byte("V", self::VERSION);
     $nbt->InhabitedTime = new Long("InhabitedTime", 0);
     $biomes = str_repeat(Binary::writeByte(-1), 256);
     $nbt->Biomes = new ByteArray("Biomes", $biomes);
     $nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 156, Binary::readInt("…²J")));
     $nbt->HeightMap = new IntArray("HeightMap", array_fill(0, 256, 127));
     $nbt->Sections = new Enum("Sections", []);
     $nbt->Sections->setTagType(NBT::TAG_Compound);
     $nbt->Entities = new Enum("Entities", []);
     $nbt->Entities->setTagType(NBT::TAG_Compound);
     $nbt->TileEntities = new Enum("TileEntities", []);
     $nbt->TileEntities->setTagType(NBT::TAG_Compound);
     $nbt->TileTicks = new Enum("TileTicks", []);
     $nbt->TileTicks->setTagType(NBT::TAG_Compound);
     $writer = new NBT(NBT::BIG_ENDIAN);
     $nbt->setName("Level");
     $writer->setData(new Compound("", ["Level" => $nbt]));
     $chunkData = $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL);
     $this->saveChunk($x, $z, $chunkData);
 }
示例#3
0
 /**
  * @param LevelProvider  $provider
  * @param int            $x
  * @param int            $z
  * @param ChunkSection[] $sections
  * @param string         $biomeIds
  * @param int[]          $biomeColors
  * @param int[]          $heightMap
  * @param Compound[]     $entities
  * @param Compound[]     $tiles
  *
  * @throws ChunkException
  */
 protected function __construct($provider, $x, $z, array $sections, $biomeIds = null, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = [])
 {
     $this->provider = $provider;
     $this->x = (int) $x;
     $this->z = (int) $z;
     foreach ($sections as $Y => $section) {
         if ($section instanceof ChunkSection) {
             $this->sections[$Y] = $section;
         } else {
             throw new ChunkException("Received invalid ChunkSection instance");
         }
         if ($Y >= self::SECTION_COUNT) {
             throw new ChunkException("Invalid amount of chunks");
         }
     }
     if (strlen($biomeIds) === 256) {
         $this->biomeIds = $biomeIds;
     } else {
         $this->biomeIds = str_repeat("", 256);
     }
     if (count($biomeColors) === 256) {
         $this->biomeColors = $biomeColors;
     } else {
         $this->biomeColors = array_fill(0, 256, Binary::readInt("…²J"));
     }
     if (count($heightMap) === 256) {
         $this->heightMap = $heightMap;
     } else {
         $this->heightMap = array_fill(0, 256, 127);
     }
     $this->NBTtiles = $tiles;
     $this->NBTentities = $entities;
 }
示例#4
0
 public function handle($address, $port, $packet)
 {
     $offset = 2;
     $packetType = ord($packet[$offset++]);
     $sessionID = Binary::readInt(substr($packet, $offset, 4));
     $offset += 4;
     $payload = substr($packet, $offset);
     switch ($packetType) {
         case self::HANDSHAKE:
             //Handshake
             $reply = chr(self::HANDSHAKE);
             $reply .= Binary::writeInt($sessionID);
             $reply .= self::getTokenString($this->token, $address) . "";
             $this->server->getNetwork()->sendPacket($address, $port, $reply);
             break;
         case self::STATISTICS:
             //Stat
             $token = Binary::readInt(substr($payload, 0, 4));
             if ($token !== self::getTokenString($this->token, $address) and $token !== self::getTokenString($this->lastToken, $address)) {
                 break;
             }
             $reply = chr(self::STATISTICS);
             $reply .= Binary::writeInt($sessionID);
             if ($this->timeout < microtime(true)) {
                 $this->regenerateInfo();
             }
             if (strlen($payload) === 8) {
                 $reply .= $this->longData;
             } else {
                 $reply .= $this->shortData;
             }
             $this->server->getNetwork()->sendPacket($address, $port, $reply);
             break;
     }
 }
示例#5
0
 public function __construct($level, Compound $nbt)
 {
     $this->nbt = $nbt;
     if (!isset($this->nbt->Entities) or !$this->nbt->Entities instanceof Enum) {
         $this->nbt->Entities = new Enum("Entities", []);
         $this->nbt->Entities->setTagType(NBT::TAG_Compound);
     }
     if (!isset($this->nbt->TileEntities) or !$this->nbt->TileEntities instanceof Enum) {
         $this->nbt->TileEntities = new Enum("TileEntities", []);
         $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
     }
     if (!isset($this->nbt->TileTicks) or !$this->nbt->TileTicks instanceof Enum) {
         $this->nbt->TileTicks = new Enum("TileTicks", []);
         $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
     }
     if (!isset($this->nbt->Sections) or !$this->nbt->Sections instanceof Enum) {
         $this->nbt->Sections = new Enum("Sections", []);
         $this->nbt->Sections->setTagType(NBT::TAG_Compound);
     }
     if (!isset($this->nbt->Biomes) or !$this->nbt->Biomes instanceof ByteArray) {
         $this->nbt->Biomes = new ByteArray("Biomes", \str_repeat("", 256));
     }
     if (!isset($this->nbt->BiomeColors) or !$this->nbt->BiomeColors instanceof IntArray) {
         $this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 256, Binary::readInt("…²J")));
     }
     if (!isset($this->nbt->HeightMap) or !$this->nbt->HeightMap instanceof IntArray) {
         $this->nbt->HeightMap = new IntArray("HeightMap", \array_fill(0, 256, 127));
     }
     $sections = [];
     foreach ($this->nbt->Sections as $section) {
         if ($section instanceof Compound) {
             $y = (int) $section["Y"];
             if ($y < 8) {
                 $sections[$y] = new ChunkSection($section);
             }
         }
     }
     for ($y = 0; $y < 8; ++$y) {
         if (!isset($sections[$y])) {
             $sections[$y] = new EmptyChunkSection($y);
         }
     }
     parent::__construct($level, (int) $this->nbt["xPos"], (int) $this->nbt["zPos"], $sections, $this->nbt->Biomes->getValue(), $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue());
     unset($this->nbt->Sections);
 }
示例#6
0
 public function __construct($level, Compound $nbt)
 {
     $this->nbt = $nbt;
     if (isset($this->nbt->Entities) and $this->nbt->Entities instanceof Enum) {
         $this->nbt->Entities->setTagType(NBT::TAG_Compound);
     } else {
         $this->nbt->Entities = new Enum("Entities", []);
         $this->nbt->Entities->setTagType(NBT::TAG_Compound);
     }
     if (isset($this->nbt->TileEntities) and $this->nbt->TileEntities instanceof Enum) {
         $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
     } else {
         $this->nbt->TileEntities = new Enum("TileEntities", []);
         $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
     }
     if (isset($this->nbt->TileTicks) and $this->nbt->TileTicks instanceof Enum) {
         $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
     } else {
         $this->nbt->TileTicks = new Enum("TileTicks", []);
         $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
     }
     if (!isset($this->nbt->Biomes) or !$this->nbt->Biomes instanceof ByteArray) {
         $this->nbt->Biomes = new ByteArray("Biomes", str_repeat("", 256));
     }
     if (!isset($this->nbt->BiomeColors) or !$this->nbt->BiomeColors instanceof IntArray) {
         $this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 256, Binary::readInt("…²J")));
     }
     if (!isset($this->nbt->HeightMap) or !$this->nbt->HeightMap instanceof IntArray) {
         $this->nbt->HeightMap = new IntArray("HeightMap", array_fill(0, 256, 127));
     }
     if (!isset($this->nbt->Blocks)) {
         $this->nbt->Blocks = new ByteArray("Blocks", str_repeat("", 32768));
     }
     if (!isset($this->nbt->Data)) {
         $this->nbt->Data = new ByteArray("Data", $half = str_repeat("", 16384));
         $this->nbt->SkyLight = new ByteArray("SkyLight", $half);
         $this->nbt->BlockLight = new ByteArray("BlockLight", $half);
     }
     parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $this->nbt->Blocks->getValue(), $this->nbt->Data->getValue(), $this->nbt->SkyLight->getValue(), $this->nbt->BlockLight->getValue(), $this->nbt->Biomes->getValue(), $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue());
     unset($this->nbt->Blocks);
     unset($this->nbt->Data);
     unset($this->nbt->SkyLight);
     unset($this->nbt->BlockLight);
 }
示例#7
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;
 }
 public function readInt($signed = true)
 {
     $int = Binary::readInt($this->read(4));
     if (!$signed and $int < 0) {
         $int += 0x100000000;
     }
     return $int;
 }
示例#9
0
 public function getInt()
 {
     return $this->endianness === self::BIG_ENDIAN ? Binary::readInt($this->get(4)) : Binary::readLInt($this->get(4));
 }
示例#10
0
 public function loadChunk($X, $Z)
 {
     if ($this->isChunkLoaded($X, $Z)) {
         return true;
     }
     $index = self::getIndex($X, $Z);
     $path = $this->getChunkPath($X, $Z);
     if (!file_exists($path)) {
         if ($this->generateChunk($X, $Z) === false) {
             return false;
         }
         if ($this->isGenerating === 0) {
             $this->populateChunk($X, $Z);
         }
         return true;
     }
     $chunk = file_get_contents($path);
     if ($chunk === false) {
         return false;
     }
     $chunk = zlib_decode($chunk);
     $offset = 0;
     $this->chunkInfo[$index] = [0 => ord($chunk[0]), 1 => Binary::readInt(substr($chunk, 1, 4))];
     $offset += 5;
     $len = Binary::readInt(substr($chunk, $offset, 4));
     $offset += 4;
     $nbt = new NBT(NBT::BIG_ENDIAN);
     $nbt->read(substr($chunk, $offset, $len));
     $this->chunkInfo[$index][2] = $nbt->getData();
     $offset += $len;
     $this->chunks[$index] = [];
     $this->chunkChange[$index] = [-1 => false];
     $this->chunkInfo[$index][3] = substr($chunk, $offset, 256);
     //Biome data
     $offset += 256;
     for ($Y = 0; $Y < 8; ++$Y) {
         if (($this->chunkInfo[$index][0] & 1 << $Y) !== 0) {
             // 4096 + 2048 + 2048, Block Data, Meta, Light
             if (strlen($this->chunks[$index][$Y] = substr($chunk, $offset, 8192)) < 8192) {
                 MainLogger::getLogger()->notice("Empty corrupt chunk detected [{$X},{$Z},:{$Y}], recovering contents");
                 $this->fillMiniChunk($X, $Z, $Y);
             }
             $offset += 8192;
         } else {
             $this->chunks[$index][$Y] = false;
         }
     }
     if ($this->isGenerating === 0 and !$this->isPopulated($X, $Z)) {
         $this->populateChunk($X, $Z);
     }
     return true;
 }
示例#11
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;
 }
示例#12
0
 public function doSlowCleanUp()
 {
     for ($i = 0; $i < 1024; ++$i) {
         if ($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0) {
             continue;
         }
         fseek($this->filePointer, $this->locationTable[$i][0] << 12);
         $chunk = fread($this->filePointer, $this->locationTable[$i][1] << 12);
         $length = Binary::readInt(substr($chunk, 0, 4));
         if ($length <= 1) {
             $this->locationTable[$i] = [0, 0, 0];
             //Non-generated chunk, remove it from index
         }
         try {
             $chunk = zlib_decode(substr($chunk, 5));
         } catch (\Exception $e) {
             $this->locationTable[$i] = [0, 0, 0];
             //Corrupted chunk, remove it
             continue;
         }
         $chunk = chr(self::COMPRESSION_ZLIB) . zlib_encode($chunk, ZLIB_ENCODING_DEFLATE, 9);
         $chunk = Binary::writeInt(strlen($chunk)) . $chunk;
         $sectors = (int) ceil(strlen($chunk) / 4096);
         if ($sectors > $this->locationTable[$i][1]) {
             $this->locationTable[$i][0] = $this->lastSector + 1;
             $this->lastSector += $sectors;
         }
         fseek($this->filePointer, $this->locationTable[$i][0] << 12);
         fwrite($this->filePointer, str_pad($chunk, $sectors << 12, "", STR_PAD_RIGHT));
     }
     $this->writeLocationTable();
     $n = $this->cleanGarbage();
     $this->writeLocationTable();
     return $n;
 }
 protected function getInt()
 {
     return Binary::readInt($this->get(4));
 }
示例#14
0
 public function handle($address, $port, $packet)
 {
     $offset = 2;
     $packetType = ord($packet[$offset++]);
     $sessionID = Binary::readInt(substr($packet, $offset, 4));
     $offset += 4;
     $payload = substr($packet, $offset);
     switch ($packetType) {
         case self::HANDSHAKE:
             //Handshake
             $reply = chr(self::HANDSHAKE);
             $reply .= Binary::writeInt($sessionID);
             $reply .= self::getTokenString($this->token, $address) . "";
             $this->server->sendPacket($address, $port, $reply);
             break;
         case self::STATISTICS:
             //Stat
             $token = Binary::readInt(substr($payload, 0, 4));
             if ($token !== self::getTokenString($this->token, $address) and $token !== self::getTokenString($this->lastToken, $address)) {
                 break;
             }
             $reply = chr(self::STATISTICS);
             $reply .= Binary::writeInt($sessionID);
             if (strlen($payload) === 8) {
                 if ($this->timeout < microtime(true)) {
                     $this->regenerateInfo();
                 }
                 $reply .= $this->longData;
             } else {
                 $reply .= $this->server->getServerName() . "" . (($this->server->getGamemode() & 0x1) === 0 ? "SMP" : "CMP") . "" . ($this->server->getDefaultLevel() === null ? "unknown" : $this->server->getDefaultLevel()->getName()) . "" . count($this->server->getOnlinePlayers()) . "" . $this->server->getMaxPlayers() . "" . Binary::writeLShort($this->server->getPort()) . $this->server->getIp() . "";
             }
             $this->server->sendPacket($address, $port, $reply);
             break;
     }
 }
示例#15
0
 public static function decompressName($compressed)
 {
     $int = substr($compressed, 0, 4);
     $long = substr($compressed, 4, 8);
     /** @var int $value */
     $value = Binary::readInt($int, false);
     $value <<= 32;
     $value += Binary::readLong($long, false);
     $out = "";
     for ($offset = 0; $offset <= 16; $offset++) {
         $ord = $value & 0b111111;
         if (0 <= $ord and $ord <= 9) {
             $chr = chr(ord("0") + $ord);
         } else {
             $ord -= 10;
             if ($ord <= 25) {
                 $chr = chr(ord("a") + $ord);
             } else {
                 $chr = "_";
             }
             // corrupted databases will lead to a large amount of underscores
         }
         $out = $chr . $out;
     }
     return $out;
 }
示例#16
0
 public function getInt(bool $network = false)
 {
     if ($network === true) {
         return Binary::readVarInt($this);
     }
     return $this->endianness === self::BIG_ENDIAN ? Binary::readInt($this->get(4)) : Binary::readLInt($this->get(4));
 }
 public function handlePackets()
 {
     while (strlen($packet = $this->generationThread->readThreadToMainPacket()) > 0) {
         $pid = ord($packet[0]);
         $offset = 1;
         if ($pid === GenerationManager::PACKET_REQUEST_CHUNK) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $chunkX = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $chunkZ = Binary::readInt(substr($packet, $offset, 4));
             $this->handleRequest($levelID, $chunkX, $chunkZ);
         } elseif ($pid === GenerationManager::PACKET_SEND_CHUNK) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $len = ord($packet[$offset++]);
             /** @var FullChunk $class */
             $class = substr($packet, $offset, $len);
             $offset += $len;
             $level = $this->server->getLevel($levelID);
             if ($level instanceof Level) {
                 $chunk = $class::fromBinary(substr($packet, $offset), $level->getProvider());
                 $this->receiveChunk($levelID, $chunk);
             }
         }
     }
 }
示例#18
0
 public function readPacket()
 {
     $packets = [];
     if ($this->receiveBuffer !== "" && strlen($this->receiveBuffer) > 0) {
         $len = strlen($this->receiveBuffer);
         $offset = 0;
         while ($offset < $len) {
             if ($offset > $len - 4) {
                 break;
             }
             $pkLen = Binary::readInt(substr($this->receiveBuffer, $offset, 4));
             $offset += 4;
             if ($pkLen <= $len - $offset) {
                 $buf = substr($this->receiveBuffer, $offset, $pkLen);
                 $offset += $pkLen;
                 $packets[] = $buf;
             } else {
                 $offset -= 4;
                 break;
             }
         }
         if ($offset < $len) {
             $this->receiveBuffer = substr($this->receiveBuffer, $offset);
         } else {
             $this->receiveBuffer = "";
         }
     }
     return $packets;
 }
示例#19
0
 protected function readPacket()
 {
     if (strlen($packet = $this->thread->readMainToThreadPacket()) > 0) {
         $pid = ord($packet[0]);
         $offset = 1;
         if ($pid === self::PACKET_REQUEST_CHUNK) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $chunkX = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $chunkZ = Binary::readInt(substr($packet, $offset, 4));
             $this->enqueueChunk($levelID, $chunkX, $chunkZ);
         } elseif ($pid === self::PACKET_SEND_CHUNK) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $len = ord($packet[$offset++]);
             /** @var FullChunk $class */
             $class = substr($packet, $offset, $len);
             $offset += $len;
             $chunk = $class::fromBinary(substr($packet, $offset));
             $this->receiveChunk($levelID, $chunk);
         } elseif ($pid === self::PACKET_OPEN_LEVEL) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $seed = Binary::readInt(substr($packet, $offset, 4));
             $offset += 4;
             $len = Binary::readShort(substr($packet, $offset, 2));
             $offset += 2;
             $class = substr($packet, $offset, $len);
             $offset += $len;
             $options = unserialize(substr($packet, $offset));
             $this->openLevel($levelID, $seed, $class, $options);
         } elseif ($pid === self::PACKET_CLOSE_LEVEL) {
             $levelID = Binary::readInt(substr($packet, $offset, 4));
             $this->closeLevel($levelID);
         } elseif ($pid === self::PACKET_ADD_NAMESPACE) {
             $len = Binary::readShort(substr($packet, $offset, 2));
             $offset += 2;
             $namespace = substr($packet, $offset, $len);
             $offset += $len;
             $path = substr($packet, $offset);
             $this->loader->addPath($path);
         } elseif ($pid === self::PACKET_SHUTDOWN) {
             foreach ($this->levels as $level) {
                 $level->shutdown();
             }
             $this->levels = [];
             $this->shutdown = true;
         }
     } elseif (count($this->thread->getInternalQueue()) === 0) {
         $this->thread->synchronized(function () {
             $this->thread->wait(50000);
         });
     }
 }
示例#20
0
 public static function fromFastBinary($data, LevelProvider $provider = null)
 {
     try {
         $offset = 0;
         $chunk = new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, null);
         $chunk->provider = $provider;
         $chunk->x = Binary::readInt(substr($data, $offset, 4));
         $offset += 4;
         $chunk->z = Binary::readInt(substr($data, $offset, 4));
         $offset += 4;
         $chunk->blocks = substr($data, $offset, 32768);
         $offset += 32768;
         $chunk->data = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->skyLight = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->blockLight = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->heightMap = array_values(unpack("C*", substr($data, $offset, 256)));
         $offset += 256;
         $chunk->biomeColors = array_values(unpack("N*", substr($data, $offset, 1024)));
         $offset += 1024;
         $flags = ord($data[$offset++]);
         $chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", $flags & 0b1);
         $chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", $flags >> 1 & 0b1);
         $chunk->nbt->LightPopulated = new Byte("LightPopulated", $flags >> 2 & 0b1);
         return $chunk;
     } catch (\Exception $e) {
         return null;
     }
 }
示例#21
0
 public function processBatch(BatchPacket $packet, Player $p)
 {
     $str = zlib_decode($packet->payload, 1024 * 1024 * 64);
     //Max 64MB
     $len = strlen($str);
     $offset = 0;
     try {
         while ($offset < $len) {
             $pkLen = Binary::readInt(substr($str, $offset, 4));
             $offset += 4;
             $buf = substr($str, $offset, $pkLen);
             $offset += $pkLen;
             if (($pk = $this->getPacket(ord($buf[1]))) !== null) {
                 if ($pk::NETWORK_ID === Info::BATCH_PACKET) {
                     throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
                 }
                 $pk->setBuffer($buf, 2);
                 $pk->decode();
                 $p->handleDataPacket($pk);
                 if ($pk->getOffset() <= 0) {
                     return;
                 }
             }
         }
     } catch (\Throwable $e) {
         if (\pocketmine\DEBUG > 1) {
             $logger = $this->server->getLogger();
             if ($logger instanceof MainLogger) {
                 $logger->debug("BatchPacket " . " 0x" . bin2hex($packet->payload));
                 $logger->logException($e);
             }
         }
     }
 }
示例#22
0
 /**
  * @param int           $chunkX
  * @param int           $chunkZ
  * @param LevelProvider $provider
  *
  * @return Chunk
  */
 public static function getEmptyChunk($chunkX, $chunkZ, LevelProvider $provider = null)
 {
     try {
         $chunk = new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, null);
         $chunk->x = $chunkX;
         $chunk->z = $chunkZ;
         $chunk->data = str_repeat("", 16384);
         $chunk->blocks = $chunk->data . $chunk->data;
         $chunk->skyLight = str_repeat("ÿ", 16384);
         $chunk->blockLight = $chunk->data;
         $chunk->heightMap = array_fill(0, 256, 0);
         $chunk->biomeColors = array_fill(0, 256, Binary::readInt("…²J"));
         $chunk->nbt->V = new Byte("V", 1);
         $chunk->nbt->InhabitedTime = new Long("InhabitedTime", 0);
         $chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", 0);
         $chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", 0);
         $chunk->nbt->LightPopulated = new Byte("LightPopulated", 0);
         return $chunk;
     } catch (\Exception $e) {
         return null;
     }
 }
示例#23
0
 public function getInt()
 {
     return Binary::readInt($this->get(4));
 }
示例#24
0
 public static function fromFastBinary($data, LevelProvider $provider = null)
 {
     try {
         $offset = 0;
         $chunk = new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, null);
         $chunk->provider = $provider;
         $chunk->x = Binary::readInt(substr($data, $offset, 4));
         $offset += 4;
         $chunk->z = Binary::readInt(substr($data, $offset, 4));
         $offset += 4;
         $chunk->blocks = substr($data, $offset, 32768);
         $offset += 32768;
         $chunk->data = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->skyLight = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->blockLight = substr($data, $offset, 16384);
         $offset += 16384;
         $chunk->biomeIds = substr($data, $offset, 256);
         $offset += 256;
         $chunk->biomeColors = [];
         $chunk->heightMap = [];
         $bc = unpack("N*", substr($data, $offset, 1024));
         $offset += 1024;
         $hm = unpack("N*", substr($data, $offset, 1024));
         $offset += 1024;
         for ($i = 0; $i < 256; ++$i) {
             $chunk->biomeColors[$i] = $bc[$i + 1];
             $chunk->heightMap[$i] = $hm[$i + 1];
         }
         $flags = ord($data[$offset++]);
         $chunk->nbt->TerrainGenerated = new Byte("TerrainGenerated", $flags & 0b1);
         $chunk->nbt->TerrainPopulated = new Byte("TerrainPopulated", $flags >> 1);
         return $chunk;
     } catch (\Exception $e) {
         return null;
     }
 }