PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
ChunkRequestTask.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 
31 
33 
34  protected $levelId;
35  protected $chunkX;
36  protected $chunkZ;
37  protected $compressionLevel;
38 
40  protected $sections;
42  protected $biomeIds;
44  protected $biomeColors;
45 
46  protected $tiles;
47 
48  public function __construct(Anvil $level, $levelId, $chunkX, $chunkZ){
49  $this->levelId = $levelId;
50  $this->chunkX = $chunkX;
51  $this->chunkZ = $chunkZ;
52  $chunk = $level->getChunk($chunkX, $chunkZ, false);
53  if(!($chunk instanceof Chunk)){
54  throw new ChunkException("Invalid Chunk sent");
55  }
56  $this->biomeIds = $chunk->getBiomeIdArray();
57  $this->biomeColors = $chunk->getBiomeColorArray();
58 
59  $this->sections = $chunk->getSections();
60 
61  $tiles = "";
62  $nbt = new NBT(NBT::LITTLE_ENDIAN);
63  foreach($chunk->getTiles() as $tile){
64  if($tile instanceof Spawnable){
65  $nbt->setData($tile->getSpawnCompound());
66  $tiles .= $nbt->write();
67  }
68  }
69 
70  $this->tiles = $tiles;
71 
72  $this->compressionLevel = Level::$COMPRESSION_LEVEL;
73 
74  }
75 
76  public function onRun(){
77  $orderedIds = "";
78  $orderedData = "";
79  $orderedSkyLight = "";
80  $orderedLight = "";
81 
82  $ids = "";
83  $meta = "";
84  $blockLight = "";
85  $skyLight = "";
86 
87  foreach($this->sections as $section){
88  $ids .= $section->getIdArray();
89  $meta .= $section->getDataArray();
90  $blockLight .= $section->getLightArray();
91  $skyLight .= $section->getSkyLightArray();
92  }
93 
94  for($x = 0; $x < 16; ++$x){
95  for($z = 0; $z < 16; ++$z){
96  $orderedIds .= $this->getColumn($ids, $x, $z);
97  $orderedData .= $this->getHalfColumn($meta, $x, $z);
98  $orderedSkyLight .= $this->getHalfColumn($skyLight, $x, $z);
99  $orderedLight .= $this->getHalfColumn($blockLight, $x, $z);
100  }
101  }
102 
103  $biomeColors = pack("N*", ...$this->biomeColors);
104 
105  $ordered = zlib_encode(Binary::writeLInt($this->chunkX) . Binary::writeLInt($this->chunkZ) . $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $this->biomeIds . $biomeColors . $this->tiles, ZLIB_ENCODING_DEFLATE, $this->compressionLevel);
106 
107  $this->setResult($ordered);
108  }
109 
110  public function getColumn(&$data, $x, $z){
111  $i = ($z << 4) + $x;
112  $column = "";
113  for($y = 0; $y < 128; ++$y){
114  $column .= $data{($y << 8) + $i};
115  }
116 
117  return $column;
118  }
119 
120  public function getHalfColumn(&$data, $x, $z){
121  $i = ($z << 3) + ($x >> 1);
122  $column = "";
123  if(($x & 1) === 0){
124  for($y = 0; $y < 128; $y += 2){
125  $column .= ($data{($y << 7) + $i} & "\x0f") | chr((ord($data{(($y + 1) << 7) + $i}) & 0x0f) << 4);
126  }
127  }else{
128  for($y = 0; $y < 128; $y += 2){
129  $column .= chr((ord($data{($y << 7) + $i}) & 0xf0) >> 4) | ($data{(($y + 1) << 7) + $i} & "\xf0");
130  }
131  }
132 
133  return $column;
134  }
135 
136  public function onCompletion(Server $server){
137  $level = $server->getLevel($this->levelId);
138  if($level instanceof Level and $this->hasResult()){
139  $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $this->getResult());
140  }
141  }
142 
143 }
getChunk($chunkX, $chunkZ, $create=false)
Definition: Anvil.php:89
getLevel($levelId)
Definition: Server.php:931