diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 69144cde5..b3066aa14 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -382,6 +382,7 @@ class Level implements ChunkManager, Metadatable{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); $this->generator = GeneratorManager::getGenerator($this->provider->getGenerator()); + //TODO: validate generator options $this->folderName = $name; diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 1efa82c33..153fb5783 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -33,10 +33,11 @@ use pocketmine\level\generator\populator\Ore; use pocketmine\level\generator\populator\Populator; use pocketmine\math\Vector3; use pocketmine\utils\Random; +use function array_map; use function count; use function explode; +use function preg_match; use function preg_match_all; -use function str_replace; class Flat extends Generator{ /** @var Chunk */ @@ -62,6 +63,11 @@ class Flat extends Generator{ return "flat"; } + /** + * @param array $options + * + * @throws InvalidGeneratorOptionsException + */ public function __construct(array $options = []){ $this->options = $options; if(isset($this->options["preset"]) and $this->options["preset"] != ""){ @@ -89,13 +95,28 @@ class Flat extends Generator{ } } + /** + * @param string $layers + * + * @return int[][] + * @throws InvalidGeneratorOptionsException + */ public static function parseLayers(string $layers) : array{ $result = []; - preg_match_all('#^(([0-9]*x|)([0-9]{1,3})(|:[0-9]{0,2}))$#m', str_replace(",", "\n", $layers), $matches); + $split = array_map('\trim', explode(',', $layers)); $y = 0; - foreach($matches[3] as $i => $b){ - $b = ItemFactory::fromString($b . $matches[4][$i]); - $cnt = $matches[2][$i] === "" ? 1 : (int) $matches[2][$i]; + foreach($split as $line){ + preg_match('#^(?:(\d+)x)?(.+)$#', $line, $matches); + if(count($matches) !== 3){ + throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\""); + } + + $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; + try{ + $b = ItemFactory::fromString($matches[2])->getBlock(); + }catch(\InvalidArgumentException $e){ + throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); + } for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ $result[$cY] = [$b->getId(), $b->getDamage()]; } @@ -113,6 +134,7 @@ class Flat extends Generator{ $this->floorLevel = count($this->structure); + //TODO: more error checking preg_match_all('#(([0-9a-z_]{1,})\(?([0-9a-z_ =:]{0,})\)?),?#', $options, $matches); foreach($matches[2] as $i => $option){ $params = true; diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/level/generator/Generator.php index b72c0a7ce..dba5fa8a8 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/level/generator/Generator.php @@ -58,6 +58,11 @@ abstract class Generator{ /** @var Random */ protected $random; + /** + * @param array $settings + * + * @throws InvalidGeneratorOptionsException + */ abstract public function __construct(array $settings = []); diff --git a/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php b/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php new file mode 100644 index 000000000..9489589f0 --- /dev/null +++ b/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php @@ -0,0 +1,28 @@ +