48 private const TAG_DAY_TIME =
"DayTime";
49 private const TAG_DIFFICULTY =
"Difficulty";
50 private const TAG_FORMAT_VERSION =
"version";
51 private const TAG_GAME_RULES =
"GameRules";
52 private const TAG_GAME_TYPE =
"GameType";
53 private const TAG_GENERATOR_VERSION =
"generatorVersion";
54 private const TAG_HARDCORE =
"hardcore";
55 private const TAG_INITIALIZED =
"initialized";
56 private const TAG_LAST_PLAYED =
"LastPlayed";
57 private const TAG_RAINING =
"raining";
58 private const TAG_RAIN_TIME =
"rainTime";
59 private const TAG_ROOT_DATA =
"Data";
60 private const TAG_SIZE_ON_DISK =
"SizeOnDisk";
61 private const TAG_THUNDERING =
"thundering";
62 private const TAG_THUNDER_TIME =
"thunderTime";
64 public static function generate(
string $path,
string $name,
WorldCreationOptions $options,
int $version = 19133) :
void{
67 $worldData = CompoundTag::create()
68 ->setByte(self::TAG_HARDCORE, 0)
69 ->setByte(self::TAG_DIFFICULTY, $options->getDifficulty())
70 ->setByte(self::TAG_INITIALIZED, 1)
71 ->setInt(self::TAG_GAME_TYPE, 0)
72 ->setInt(self::TAG_GENERATOR_VERSION, 1)
73 ->setInt(self::TAG_SPAWN_X, $options->getSpawnPosition()->getFloorX())
74 ->setInt(self::TAG_SPAWN_Y, $options->getSpawnPosition()->getFloorY())
75 ->setInt(self::TAG_SPAWN_Z, $options->getSpawnPosition()->getFloorZ())
76 ->setInt(self::TAG_FORMAT_VERSION, $version)
77 ->setInt(self::TAG_DAY_TIME, 0)
78 ->setLong(self::TAG_LAST_PLAYED, (
int) (microtime(
true) * 1000))
79 ->setLong(self::TAG_RANDOM_SEED, $options->getSeed())
80 ->setLong(self::TAG_SIZE_ON_DISK, 0)
81 ->setLong(self::TAG_TIME, 0)
82 ->setString(self::TAG_GENERATOR_NAME, GeneratorManager::getInstance()->getGeneratorName($options->
getGeneratorClass()))
83 ->setString(self::TAG_GENERATOR_OPTIONS, $options->getGeneratorOptions())
84 ->setString(self::TAG_LEVEL_NAME, $name)
88 $buffer = zlib_encode($nbt->write(
new TreeRoot(CompoundTag::create()->setTag(self::TAG_ROOT_DATA, $worldData))), ZLIB_ENCODING_GZIP);
89 file_put_contents(Path::join($path,
"level.dat"), $buffer);
94 $rawLevelData =
Filesystem::fileGetContents($this->dataPath);
95 }
catch(\RuntimeException $e){
98 $nbt =
new BigEndianNbtSerializer();
99 $decompressed = @zlib_decode($rawLevelData);
100 if($decompressed ===
false){
104 $worldData = $nbt->read($decompressed)->mustGetCompoundTag();
105 }
catch(NbtDataException $e){
109 $dataTag = $worldData->getTag(self::TAG_ROOT_DATA);
111 throw new CorruptedWorldException(
"Missing '" . self::TAG_ROOT_DATA .
"' key or wrong type");
116 protected function fix() : void{
117 $generatorNameTag = $this->compoundTag->getTag(self::TAG_GENERATOR_NAME);
118 if(!($generatorNameTag instanceof
StringTag)){
119 $this->compoundTag->setString(self::TAG_GENERATOR_NAME,
"default");
120 }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($generatorNameTag->getValue())) !==
null){
121 $this->compoundTag->setString(self::TAG_GENERATOR_NAME, $generatorName);
124 if(!($this->compoundTag->getTag(self::TAG_GENERATOR_OPTIONS) instanceof
StringTag)){
125 $this->compoundTag->setString(self::TAG_GENERATOR_OPTIONS,
"");
133 $buffer = Utils::assumeNotFalse(zlib_encode($nbt->write(
new TreeRoot(CompoundTag::create()->setTag(self::TAG_ROOT_DATA, $this->compoundTag))), ZLIB_ENCODING_GZIP));
134 Filesystem::safeFilePutContents($this->dataPath, $buffer);
138 return $this->compoundTag->getByte(self::TAG_DIFFICULTY,
World::DIFFICULTY_NORMAL);
142 $this->compoundTag->setByte(self::TAG_DIFFICULTY, $difficulty);
146 return $this->compoundTag->getInt(self::TAG_RAIN_TIME, 0);
150 $this->compoundTag->setInt(self::TAG_RAIN_TIME, $ticks);
154 return (float) $this->compoundTag->getByte(self::TAG_RAINING, 0);
158 $this->compoundTag->setByte(self::TAG_RAINING, (int) ceil($level));
162 return $this->compoundTag->getInt(self::TAG_THUNDER_TIME, 0);
166 $this->compoundTag->setInt(self::TAG_THUNDER_TIME, $ticks);
170 return (float) $this->compoundTag->getByte(self::TAG_THUNDERING, 0);
174 $this->compoundTag->setByte(self::TAG_THUNDERING, (int) ceil($level));