PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
anvil/Chunk.php
1 <?php
2 
3 /*
4  *
5  * ____ _ _ __ __ _ __ __ ____
6  * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7  * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8  * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9  * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * @author PocketMine Team
17  * @link http://www.pocketmine.net/
18  *
19  *
20 */
21 
22 namespace pocketmine\level\format\anvil;
23 
36 
37 class Chunk extends BaseChunk{
38 
40  protected $nbt;
41 
42  public function __construct($level, Compound $nbt){
43  $this->nbt = $nbt;
44 
45  if(!isset($this->nbt->Entities) or !($this->nbt->Entities instanceof Enum)){
46  $this->nbt->Entities = new Enum("Entities", []);
47  $this->nbt->Entities->setTagType(NBT::TAG_Compound);
48  }
49 
50  if(!isset($this->nbt->TileEntities) or !($this->nbt->TileEntities instanceof Enum)){
51  $this->nbt->TileEntities = new Enum("TileEntities", []);
52  $this->nbt->TileEntities->setTagType(NBT::TAG_Compound);
53  }
54 
55  if(!isset($this->nbt->TileTicks) or !($this->nbt->TileTicks instanceof Enum)){
56  $this->nbt->TileTicks = new Enum("TileTicks", []);
57  $this->nbt->TileTicks->setTagType(NBT::TAG_Compound);
58  }
59 
60  if(!isset($this->nbt->Sections) or !($this->nbt->Sections instanceof Enum)){
61  $this->nbt->Sections = new Enum("Sections", []);
62  $this->nbt->Sections->setTagType(NBT::TAG_Compound);
63  }
64 
65  if(!isset($this->nbt->Biomes) or !($this->nbt->Biomes instanceof ByteArray)){
66  $this->nbt->Biomes = new ByteArray("Biomes", str_repeat("\x01", 256));
67  }
68 
69  if(!isset($this->nbt->BiomeColors) or !($this->nbt->BiomeColors instanceof IntArray)){
70  $this->nbt->BiomeColors = new IntArray("BiomeColors", array_fill(0, 256, Binary::readInt("\x00\x85\xb2\x4a")));
71  }
72 
73  if(!isset($this->nbt->HeightMap) or !($this->nbt->HeightMap instanceof IntArray)){
74  $this->nbt->HeightMap = new IntArray("HeightMap", array_fill(0, 256, 127));
75  }
76 
77  $sections = [];
78  foreach($this->nbt->Sections as $section){
79  if($section instanceof Compound){
80  $y = (int) $section["Y"];
81  if($y < 8){
82  $sections[$y] = new ChunkSection($section);
83  }
84  }
85  }
86  for($y = 0; $y < 8; ++$y){
87  if(!isset($sections[$y])){
88  $sections[$y] = new EmptyChunkSection($y);
89  }
90  }
91 
92  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());
93 
94  unset($this->nbt->Sections);
95  }
96 
100  public function isPopulated(){
101  return $this->nbt["TerrainPopulated"] > 0;
102  }
103 
107  public function setPopulated($value = 1){
108  $this->nbt->TerrainPopulated = new Byte("TerrainPopulated", $value);
109  }
110 
114  public function isGenerated(){
115  return $this->nbt["TerrainPopulated"] > 0 or (isset($this->nbt->TerrainGenerated) and $this->nbt["TerrainGenerated"] > 0);
116  }
117 
121  public function setGenerated($value = 1){
122  $this->nbt->TerrainGenerated = new Byte("TerrainGenerated", $value);
123  }
124 
128  public function getNBT(){
129  return $this->nbt;
130  }
131 
138  public static function fromBinary($data, LevelProvider $provider = null){
139  $nbt = new NBT(NBT::BIG_ENDIAN);
140 
141  try{
142  $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
143  $chunk = $nbt->getData();
144 
145  if(!isset($chunk->Level) or !($chunk->Level instanceof Compound)){
146  return null;
147  }
148 
149  return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level);
150  }catch(\Exception $e){
151  return null;
152  }
153  }
154 
155  public function toBinary(){
156  $nbt = clone $this->getNBT();
157 
158  $nbt->xPos = new Int("xPos", $this->x);
159  $nbt->zPos = new Int("zPos", $this->z);
160 
161  $nbt->Sections = new Enum("Sections", []);
162  $nbt->Sections->setTagType(NBT::TAG_Compound);
163  foreach($this->getSections() as $section){
164  if($section instanceof EmptyChunkSection){
165  continue;
166  }
167  $nbt->Sections[$section->getY()] = new Compound(null, [
168  "Y" => new Byte("Y", $section->getY()),
169  "Blocks" => new ByteArray("Blocks", $section->getIdArray()),
170  "Data" => new ByteArray("Data", $section->getDataArray()),
171  "BlockLight" => new ByteArray("BlockLight", $section->getLightArray()),
172  "SkyLight" => new ByteArray("SkyLight", $section->getSkyLightArray())
173  ]);
174  }
175 
176  $nbt->Biomes = new ByteArray("Biomes", $this->getBiomeIdArray());
177  $nbt->BiomeColors = new IntArray("BiomeColors", $this->getBiomeColorArray());
178 
179  $nbt->HeightMap = new IntArray("HeightMap", $this->getHeightMapArray());
180 
181  $entities = [];
182 
183  foreach($this->getEntities() as $entity){
184  if(!($entity instanceof Player) and !$entity->closed){
185  $entity->saveNBT();
186  $entities[] = $entity->namedtag;
187  }
188  }
189 
190  $nbt->Entities = new Enum("Entities", $entities);
191  $nbt->Entities->setTagType(NBT::TAG_Compound);
192 
193 
194  $tiles = [];
195  foreach($this->getTiles() as $tile){
196  $tile->saveNBT();
197  $tiles[] = $tile->namedtag;
198  }
199 
200  $nbt->TileEntities = new Enum("TileEntities", $tiles);
201  $nbt->TileEntities->setTagType(NBT::TAG_Compound);
202  $writer = new NBT(NBT::BIG_ENDIAN);
203  $nbt->setName("Level");
204  $writer->setData(new Compound("", ["Level" => $nbt]));
205 
206  return $writer->writeCompressed(ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL);
207  }
208 }
static fromBinary($data, LevelProvider $provider=null)